Dynamic JSON powered Hype project -- How to apply JS function to button using JSON and JS


(Stephen G) #1

Hi i have a button on stage and am populating the element with a value using json.

I would like to apply a function that i have created already to the button using javascript.

Is there an easy way to do this? My thoughts are it should be something like…

document.getElementById('S06Ans1').innerHTML = data.answers[0].ans1;
document.getElementById('S06Ans1').function(correctAnswer);

Also is there a way to apply the same json value to the hover and pressed state as the normal state on a button?
So far the hover and pressed state cant access the json data.

Many thanks.
Stephen.


#2

Hi Stephen,

A function has to be called by an event. On Document Ready, On Scene Load, On Click, On Mouseover … etc

You can do something like

document.getElementById('S06Ans1').onclick = correctAnswer;

I can see though that you are probably using some kind of event to populate the element with the JSON data. You could always just call the function like

document.getElementById('S06Ans1').innerHTML = data.answers[0].ans1;
correctAnswer;

However, without seeing a document I cannot tell if the function has been created inside this same Hype function or outside it. If the latter then the code above will throw an error.
If it’s a Hype function that you have created (for correctAnswer) then you could use Hype’s API method to call it but again this is all speculation as I haven’t seen how you have set up your document. If you could share then that would help.


(Stephen G) #3

Thanks for the reply @DBear

I guess the main thing I am trying to achieve is to play a timeline when the correct answer is pressed but use JSON to set the correct answer that fires that function as well as the answer text as it is currently is.

At the moment it works fine but I have created a correct answer array in my JSON file and would like to be able to apply that true/false value to the answer elements in hype.

This would make it a really dynamic quiz where answers could be set up in the JSON file.

Any tips would be great ! Thanks

dynamicMathsQuiz.zip (1.3 MB)


(Mark Hunte) #4

I have given all the answer button a class name and removed the on mouse actions.

The code now in S03setUp() now looks like this.

var outputText = '';
var outputImages = '';

if (!localStorage.visited) { //open 2
var xmlhttp = new XMLHttpRequest();
		var url = "${resourcesFolderName}/S03.json";
		
		xmlhttp.onreadystatechange = function() { //open 3
		    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { //open 4
		        var data = JSON.parse(xmlhttp.responseText);
		        
		        loadSceneText(data);
		        return false;
		    } // close 4
		}; // close 3data

xmlhttp.open("GET", url, true);
		xmlhttp.send();

function loadSceneText(data) { // open 5

for (var i = 0; i <= data.fractionAnswers.length; i++) {
	for (key in data.fractionAnswers[i]) {
		if (data.fractionAnswers[i].hasOwnProperty(key)) {
			outputText += '<u>' +
			data.fractionAnswers[i][key] +
			'</u>';
		} // hasOwnProperty check
	} // for each object
} //for each array element

//var updateAns1 = document.getElementById('S24Ans1');
//updateAns1.innerHTML = outputText;


//OutputImages START

//document.getElementById('S03badgeImage').innerHTML ='<img src="' + data.images[0].badgeImage + '" width="210px">';
//document.getElementById('S06queNumber').innerHTML = data.pageContent[2].queNumber;
document.getElementById('S24headingText').innerHTML = data.pageContent[0].headingText;
document.getElementById('S24questionText').innerHTML = data.pageContent[4].questionText;

//document.getElementById("S24FullWidthImage").innerHTML = '<img src="http://www.aoll.ie/moodleAssets/Maths/L3/LESSON01/images/S24WUPQ8B/' + data.images[1].fullWidthImage + '" width="996px">';
var S2Ans = document.querySelectorAll(".S24Ans");

for (var i = 0; i <= S2Ans.length; i++) {
 var answer = data.fractionAnswers[i]
 var answerBool = data.correctAnswer[i];
  for(var j in answer){
        var sub_key = j;
        var sub_val = answer[j];
       S2Ans[i].innerHTML = sub_val;
    }
  
  for(var j in answerBool){
        var sub_key = j;
        var sub_val = answerBool[j];
       answerBool = sub_val;
    }
 
   
 if (answerBool){
 S2Ans[i].addEventListener("click", function(){
    hypeDocument.functions().oneAnsCorrect(hypeDocument, this, event);
});

 }else {
 
 S2Ans[i].addEventListener("click", function(){
    hypeDocument.functions().oneAnsWrong(hypeDocument, this, event);
});
 
 }

}
 
document.getElementById('S24hintText').innerHTML = data.pageContent[5].hintText;
//OutputImages END

} //close 5 displayScene()
	} // close 2 (if else)
	 else { }
//end

This is a very, very quick look at the code so not refined.

The code looks at correctAnswer values in the json and if true adds an onclick event listner to the button that calls the oneAnsCorrect() hype function.
If false then the oneAnsWrong() function.

It also puts all the correct answers in the correct place

dynamicMathsQuiz_MH_v1.hype.zip (1.3 MB)


(Stephen G) #5

Awesome stuff @MarkHunte! You have seriously helped me out on this really appreciate you even taking the time to look over it!

I knew it could be done but my JS skills are limited to simple tasks but I understand your logic and it makes perfect sense. Its a nice solution to the problem, will test it out now with my main project!

Thanks,
Stephen.


(Mark Hunte) #6

No Prob.

You may even be able to change the code to :

var outputText = '';
var outputImages = '';

if (!localStorage.visited) { //open 2
var xmlhttp = new XMLHttpRequest();
		var url = "${resourcesFolderName}/S03.json";
		
		xmlhttp.onreadystatechange = function() { //open 3
		    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { //open 4
		        var data = JSON.parse(xmlhttp.responseText);
		        
		        loadSceneText(data);
		        return false;
		    } // close 4
		}; // close 3data

xmlhttp.open("GET", url, true);
		xmlhttp.send();

function loadSceneText(data) { // open 5
var S2Ans = document.querySelectorAll(".S24Ans");

for (var i = 0; i <= data.fractionAnswers.length; i++) {

	for (key in data.fractionAnswers[i]) {
		if (data.fractionAnswers[i].hasOwnProperty(key)) {
			outputText += '<u>' +
		 	data.fractionAnswers[i][key] +
			'</u>';
		
    }	
    
   var answer = data.fractionAnswers[i];
  for(var j in answer){
        var sub_key = j;
        var sub_val = answer[j];
       S2Ans[i].innerHTML = sub_val;
    }
    
	 var answerBool = data.correctAnswer[i];	 
		 
		 for(var j in answerBool){
        var sub_key = j;
        var sub_val = answerBool[j];
       answerBool = sub_val;
		 if (answerBool){
 S2Ans[i].addEventListener("click", function(){
    hypeDocument.functions().oneAnsCorrect(hypeDocument, this, event);
});

 }else {
 
 S2Ans[i].addEventListener("click", function(){
    hypeDocument.functions().oneAnsWrong(hypeDocument, this, event);
});
 
 }	
		} // hasOwnProperty check
	} // for each object
} //for each array element

//var updateAns1 = document.getElementById('S24Ans1');
//updateAns1.innerHTML = outputText;


//OutputImages START

//document.getElementById('S03badgeImage').innerHTML ='<img src="' + data.images[0].badgeImage + '" width="210px">';
//document.getElementById('S06queNumber').innerHTML = data.pageContent[2].queNumber;
document.getElementById('S24headingText').innerHTML = data.pageContent[0].headingText;
document.getElementById('S24questionText').innerHTML = data.pageContent[4].questionText;

//document.getElementById("S24FullWidthImage").innerHTML = '<img src="http://www.aoll.ie/moodleAssets/Maths/L3/LESSON01/images/S24WUPQ8B/' + data.images[1].fullWidthImage + '" width="996px">';

 
document.getElementById('S24hintText').innerHTML = data.pageContent[5].hintText;
//OutputImages END

} //close 5 displayScene()
	} // close 2 (if else)
	 else { }
//end

(Stephen G) #7

Cheers :beer:


(Mark Hunte) #8

Just had another look and trimmed the code I used in the for loop

for (var i = 0; i <= data.fractionAnswers.length; i++) {

 var answer = data.fractionAnswers[i]; //fractionAnswers
 var answerBool = data.correctAnswer[i];	//-- correctAnswer true of false items
  
	for (key in answer) {
		if (answer.hasOwnProperty(key)) {
			outputText += '<u>' +
		 	answer[key] +
			'</u>';
			
       S2Ans[i].innerHTML = answer[key];//-- Populate Answer Text element
        
       
		 if (answerBool[key]){//-- If correctAnswer true
 S2Ans[i].addEventListener("click", function(){
    hypeDocument.functions().oneAnsCorrect(hypeDocument, this, event);
});

 }else {//-- If correctAnswer false
 
 S2Ans[i].addEventListener("click", function(){
    hypeDocument.functions().oneAnsWrong(hypeDocument, this, event);
});
 	
		
    }// if answer true/false	
    
   
 
		} // hasOwnProperty check
	} // for each object
} //for each array element

dynamicMathsQuiz_MH_v2.hype.zip (1.3 MB)


(Stephen G) #9

Nice one @MarkHunte the code is tidy still getting my head around it fully but really pleased that it is possible to have a fully ‘dynamic’ hype app. I am launching the app in schools here in Ireland in the coming weeks and am trying to automate the development process as much as possible.

Thanks again for taking the time out of your busy day to improve my code :+1:


(Stephen G) #10

Hi @MarkHunte and go to expert @Daniel !!!

Its been a while since this post but I have a small problem wondering if you could shed some light on it for me!

I am building an ipad version of my hype app in xcode and the json wont load from the resources folder when I run it in the ios simulator, but works fine locally and on server. I tried using a url link instead of placing json files in resources folder as you have done above but cant seem to get it going.

PROBLEM:
My code linking to my test server wont load json data. Server folder permissions = 755. My thinking is that if I can get the json files to load in from server instead of resource folder then my ios app should also work inside xcode. Thanks in advance, Stephen.

var outputText = '';
if (!localStorage.visited) { //open 2
var xmlhttp = new XMLHttpRequest();
		var url = "http://www.myWebsite/JSON/L3L1_LANDINGSCREEN.json";
		
		xmlhttp.onreadystatechange = function() { //open 3
		    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { //open 4
		        var data = JSON.parse(xmlhttp.responseText);
		        
		        loadSceneText(data);
		        return false;
		    } // close 4
		}; // close 3data

xmlhttp.open("GET", url, true);
		xmlhttp.send();

function loadSceneText(data) { // open 5
var LANDText = document.querySelectorAll(".LANDText");

for (var i = 0; i <= data.pageContent.length; i++) {

 var answer = data.pageContent[i]; //wholeNumberAnswers
 //var answerBool = data.correctAnswer[i];	//-- correctAnswer true of false items
  
	for (key in answer) {
		if (answer.hasOwnProperty(key)) {
			outputText += '<u>' +
		 	answer[key] +
			'</u>';
			
       LANDText[i].innerHTML = answer[key];//-- Populate Answer Text element
                 
 
		} // hasOwnProperty check
		
		
		
	} // for each object

} //for each array element

} //close 5 displayScene()
} // close 2 (if else)
else { }
//end


(Stephen G) #11

@MarkHunte @Daniel please disregard the last post I was able to get it working.

Hosting JSON files on HTTPS server solves this problem.