0

This is a general question for which I have searched high and low to no avail, and would greatly appreciate any input.

I have a html/javascript educational quiz that loads a separate js file to retrieve an array to determine the content of the quiz. For example this retrieves the js file with an array of hard level math problems

<script type="text/javascript" src="../js/arrays/math-hard.js"></script>

I have a number of js files with arrays of different content. Another one might load English questions, etc. I need to have a variety of these quizzes, all launched from separate links in different sections of an overall interface.

Currently to create a new quiz I am duplicating the html file and changing the reference to point to the requisite js file for the array.

I would much prefer to have a single html file, and simply write different links that all load that same single html file, but dynamically substitute one of the other js array files to change the content. I cannot figure out how to do this, nor have I been able to find a published solution anywhere.

At the moment the html file is written such that it only references one of the js files that have the arrays, but it's fine to include links to all of them in that single file if that's necessary as part of achieving this functionality.

Currently I have a single html file (stripped down)

<!doctype html>
<html>
<head>
<script type="text/javascript" src="../js/quiz.js"></script>
<script type="text/javascript" src="../js/gridquiz/s-english-easy.js"></script>
</head>
<body>      
<div id="gridQuizContent" class="quiz-content">
<div id="divClick" class="quiz-click"></div>
</div>
</div>
</body>
</html>

and it load that english-easy.js, that looks basically like this (simplified)

Quiz.easy = [
    ['hi-IN', 'dog', 'cat', 'pig', 'cow'],
    ['hi-IN', 'me', 'you', 'he', 'she'],
    ['hi-IN', 'up', 'down', 'in', 'out'],
    ['hi-IN', 'hot', 'cold', 'big', 'small'],
];

And I want to write many links that simply load the same html file but change this line

<script type="text/javascript" src="../js/gridquiz/s-english-easy.js"></script>

as it loads to reference a different array.

2 Answers2

0

Personally I would use JSON files to realize this. I found a tutorial on this website, which follows the same problem "how to store quiz questions".

  • The array files are all already written in a specific way to cooperate with the main js file that drives the quiz, and they contain other code beyond that array, so I can't really take a new approach to creating the arrays themselves. I am need to load the same single html file from different links, but dynamically change the js file that it's referencing when it loads. –  Aug 08 '20 at 01:16
0

If each quiz URL looks similar to the following:

https://quiz.com/quiz.html?quiz=math-hard
https://quiz.com/quiz.html?quiz=math-easy
https://quiz.com/quiz.html?quiz=history-hard

Then you could possibly dynamically load the desired JavaScript file in a 'base' JavaScript file for quizzes by checking the URL path:

// base.js

function dynamicallyLoadScript(url) {
    // create a script DOM node
    var script = document.createElement("script");  
    // set its src to the provided URL
    script.src = url;  

    /* add it to the end of the head section of the page (could change 'head' 
       to 'body' to add it to the end of the body section instead) */
    document.head.appendChild(script);  
}


let params = new URLSearchParams(location.search);
if (params.has('quiz')) {
    dynamicallyLoadScript(params.get('quiz') + ".js");
}

So the HTML of https://quiz.com/quiz?quiz=math-hard would be similar to:

<!doctype html>
<html>
  <head>
    <script src="../js/base.js"></script>
 
    <!-- Added by 'base.js' -->
    <script src="../js/arrays/math-hard.js"></script>
  </head>
  <body>
  </body>
</html>
coltonrusch
  • 194
  • 11
  • In the three directories that you hypothesize above, do they contain files? I am hoping for a solution where I simply write a link, and there is some embellishment to the hyperlink code itself that launches that same single html file for the quiz, but swaps out the js file onload. So there aren't three directories, just three links that all lead to the same (dynamically modified) destination. –  Aug 08 '20 at 01:28
  • In a very crude way it could be though of in the same respect as loading a page that has html anchors, and then writing three links to English, Math and History, but simply go to the same page, with the #anchor modifying what you get. I know it's not really analogous, but the underlying concept is similar, in that I want to avoid the creating of any additional files or directories beyond the single html file and the js arrays –  Aug 08 '20 at 01:31
  • Okay yes, that is a bit different. Would you be able to update your question with the code you have written already? I'm confident I can help you with this, but it would be helpful for me to see what you have going on already so we're on the same page! – coltonrusch Aug 08 '20 at 01:32
  • 2
    You can put the name of the JS file in a query parameter of the link, like `quiz.html?data=math-hard.js`. Then you can construct the URL of the script from the query string. @coltonrusch – Barmar Aug 08 '20 at 02:03
  • Just be careful, as that's also a vector for cross-site scripting. – Barmar Aug 08 '20 at 02:12
  • @Barmar can you help me just a bit further, so how does that data-math-hard.js know that its replacing enlgish-easy.js? Is there more to it. I don't understand how to proceed with the last sentence of your reply - "Then you can construct the URL of the script from the query string" –  Aug 08 '20 at 02:15
  • You do it using the `dynamicallyLoadScript()` function in this answer. – Barmar Aug 08 '20 at 02:16
  • 1
    The point is that you get the `url` argument to pass to the function from the query string. – Barmar Aug 08 '20 at 02:17
  • So in this line ```dynamicallyLoadScript("../js/arrays/" + window.location.pathname + ".js");``` am I putting the path for the js files that I want to load/substitute, relative to the location of this base.js file? That's how I've done it and it's not working. –  Aug 08 '20 at 02:56
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/219442/discussion-between-thankyou-and-barmar). –  Aug 08 '20 at 03:03