use javascript to create test checker - javascript

I am a maths teacher. I want to use my school's website to allow pupils to check whether they have the correct solutions to a set of test questions given separately on paper. I wanted to give pupils a textbox in which they can enter their solution and a button to press to check if it is correct. A correct answer will display a 'correct' icon next to the question etc. I am a complete beginner but I have so far managed:
<script>
function check(z)
{
var ans = new Array
ans[0]="522"
ans[1]="144"
if (document.getElementById('response'+z).value==ans[z])
{
document.getElementById('correct' + z).style.visibility='visible'
document.getElementById('incorrect' + z).style.visibility='hidden'
}
if (document.getElementById('response'+z).value!=ans[z] && document.getElementById('response'+z).value!='')
{
document.getElementById('correct' + z).style.visibility='hidden'
document.getElementById('incorrect' + z).style.visibility='visible'
}
if (document.getElementById('response'+z).value=='')
{
document.getElementById('correct' + z).style.visibility='hidden'
document.getElementById('incorrect' + z).style.visibility='hidden'
}
}
</script>
<img id="correct0"src="correct.jpg"style="visibility:hidden"/>
<img id="incorrect0"src="incorrect.jpg"style="visibility:hidden"/>
1a
<textarea style="width: 100px; height: 20px;"id="response0"></textarea>
<button style="height: 20px"onclick="check(0)">check</button>
<br></br>
<img id="correct1"src="correct.jpg"style="visibility:hidden"/>
<img id="incorrect1"src="incorrect.jpg"style="visibility:hidden"/>
1b
<textarea style="width: 100px; height: 20px;"id="response1"></textarea>
<button style="height: 20px"onclick="check(1)">check</button>
<br></br>
This works but is obviously very clunky (I have in fact used an Excel spreadsheet to generate the html code). My questions are: Can I use javascript itself to generate the textboxes and buttons? Can I obfuscate the correct answers (if a pupils knows how to view the source of my webpage, it's game over for my exam!).
Many thanks and best wishes,

Ideally, you'll generate and verify the solutions server-side. If that's not an option, drop a reference to a hashing library in your page and validate answers against cryptographic hashes:
https://code.google.com/p/crypto-js/
You'll have to generate the hashes in your spreadsheet -- or in your own question-generation page using the same hashing library.
But beware! If there is a potential that your students are at all familiar with JavaScript, they could still easily open a JavaScript console and brute force it. Assuming reasonable answers tend to be numeric and below 1 million, it's pretty trivial ...
... One more caveat. If your answers are open text fields, you'll need to "normalize" the input before checking it. Remove extra spaces, punctuation, etc.

Obfuscating in JavaScript is not really possible - there ARE obfuscators, but there are at the same time de-obfuscators (depending on your student's knowledge, this might be an alternative)
Edit: Here is an example of an obfuscator: http://www.daftlogic.com/projects-online-javascript-obfuscator.htm, and you can also take a look at Google closure: http://closure-compiler.appspot.com/home for minifying and "kind-of-obfuscation"
But as I sad, pretty much anything can be reverted.
As far as generating the input-field and boxes ect, you should take a look at jQuery: http://jquery.com/ - it might be a little confusing in the beginning, but it is pretty easy and a BIG help with tasks like this.
If you get a little bit deeper into the topic you might want to consider server-side verification of the answers(so yout stundents can't read your code). It's not as hard as you might think, but for now jQuery should do the job.
I like your project though, I wish I had teachers like this back in the day :)

Related

I have no access to array, but need to remove commas

So this is a slightly obscure one.
I'm using Formidable Forms Pro on Wordpress to make quite a complex form. I use a Dynamic Field (who's selections come from entries from another form, hence dynamic) where users can make multiple selections.
I then use a Dynamic List Field to show the users choices more visually.
That image doesn't look too bad, not the best styling but I'm trying to get the mechanics right before making it look pretty.
The styling is in place because I'm hiding commas put in dynamically by Formidable Forms. Herein lies the issue.
This approach would work fine if I wanted the list to appear one on top of the other, but anticipating that users may want to make 10 or more selections in some cases, the list will start to take up too much of the screen.
Now, there are plenty of examples out there of how to remove delimiters from strings and arrays (I believe this is an array of strings,) but, I have no access to either to make the variable to allow that procedure to happen. Leaving it as it is means I can't use CSS Grid to style the list as my hope is to use the repeat auto-fit method to align them all side by side when there's enough space, as the commas are considered a child of the grid element like the list elements.
Inspecting the code shows that there are no html elements encasing the commas so there's no hope to use Javascript there either to remove commas within a class or whatever.
If it's possible for anyone with the know how to point me in the right direction it would be gratefully appreciated.
Since I'm using Formidable Forms to create the forms, the only code I can retrieve for you really is the output, which is what I have supplied in the images. Not ideal, I know.
The only pre-rendering code I have access to in Formidable is below. Though I suspect this will be of no use to anyone, which is why I didn't post it originally:
<div id="frm_field_[id]_container" class="frm_form_field form-field [required_class][error_class]">
<label for="field_[key]" id="field_[key]_label" class="frm_primary_label">[field_name]
<span class="frm_required">[required_label]</span>
</label>
<div class="frm_opt_container" aria-labelledby="field_[key]_label" role="group">[input]</div>
[if description]<div class="frm_description" id="frm_desc_field_[key]">[description]</div>[/if description]
[if error]<div class="frm_error" id="frm_error_field_[key]">[error]</div>[/if error]
</div>
And the rendered code:
<div id="frm_field_70_container" class="frm_form_field form-field frm_none_container frm_dynamic_data_container">
<label for="field_b0r85" id="field_b0r85_label" class="frm_primary_label">Dynamic
<span class="frm_required"></span>
</label>
<div class="frm_opt_container" aria-labelledby="field_b0r85_label" role="group" style=""><p class="frm_show_it"></p><div class="combined_field_output"><img src="http://3.11.173.147.xip.io/wp-content/uploads/formidable/2/IMG-20190512-WA0005-29-150x150.jpg" alt="Image of exercise 5545" style="width:60px;height:60px"><h3>5545</h3><p>Abdominals</p></div>, <div class="combined_field_output"><img src="http://3.11.173.147.xip.io/wp-content/uploads/formidable/2/IMG-20190512-WA0005-13-150x150.jpg" alt="Image of exercise goo" style="width:60px;height:60px"><h3>goo</h3><p>Abdominals</p></div>, <div class="combined_field_output"><img src="http://3.11.173.147.xip.io/wp-content/uploads/formidable/2/IMG-20190512-WA0005-27-150x150.jpg" alt="Image of exercise should work" style="width:60px;height:60px"><h3>should work</h3><p>Abdominals</p></div>, <div class="combined_field_output"><img src="http://3.11.173.147.xip.io/wp-content/uploads/formidable/2/IMG-20190512-WA0005-14-150x150.jpg" alt="Image of exercise Walking Lunges" style="width:60px;height:60px"><h3>Walking Lunges</h3><p>Abdominals</p></div><p></p>
5545Abdominals, gooAbdominals, should workAbdominals, Walking LungesAbdominals">
Edit: Formidable provide a way to Customise a dynamic link fieldwhich mentions nothing of the delimiter. It is my understanding that if no delimiter is specified, a comma will be added dynamically, which is what I think is happening in here. Can this PHP hook be edited to specify no delimiter be added at all?
I don't know if you have access to javascript post rendering. If you do, you can always use regex to fix your innerHTML
var text = document.getElementsByClassName("frm_opt_container")[0].innerHTML;
var reg = new RegExp("(<div class=\"combined_field_output\">.*</div>[.\n\r]*)(,)");
while(reg.test(text)){
text = text.replace(reg, "$1")
}
document.getElementsByClassName("frm_opt_container")[0].innerHTML = text

How to readout Data from a formular?

I am doing an exercise for school. Task is to readout Data from a formular. Though I do not know much and I am stuck with the first Task. The result of the first task should be: "Your name has .... Characters." So basically if I enter a name in the text field and press the submit button it should give me the .length of the Name.
HTML:
<form>
<input id="Name" type="text" name="Name">
<input id="Ausgabe" type="submit" value="Ausgabe" onclick="ausgabe"()>
<p id="yournamehas" class="ptags">Your Name has:</p>
<p id="lname" class="ptags"></p>
<p id="Characters" class="ptags"> Characters</p>
</form>
Javascript:
function namelength() {
var Namee = document.getElementById('#Name').value.length
document.getElementById('lname').innerHTML = Namee
};
function ausgabe() {
$("#Ausgabe").on("click",function(){
{
document.getElementById("#Ausgabe").innerHTML =
namelength();
}
})
};
I seriously dont know whats wrong. Can you guys help me out?
var a = document.getElementById('Name');
function ausGabe(){
var b = a.value;
var name = document.getElementById('yournamehas').innerHTML = "Your Name has:" + " " +b;
var len = document.getElementById('Characters').innerHTML = "Characters" + " " + b.length;
}
<form>
<input id="Name" type="text" name="Name">
<input id="Ausgabe" type="button" value="Ausgabe" onclick="ausGabe()">
<p id="yournamehas" class="ptags">Your Name has:</p>
<p id="lname" class="ptags"></p>
<p id="Characters" class="ptags"> Characters</p>
</form>
As this is a school exercise, some pointers may be useful, to go along with the other answer which is a working solution...
jQuery vs Vanilla JS
You are using jQuery, which is a JavaScript library (a reusable bit of code) to make some jobs easier, especially regarding manipulation of elements in the browser (DOM elements). Way back, jQuery also did a more important job of 'normalising' the different browsers (Internet Explorer, Firefox, Opera, Netscape, etc.) before they adhered to the standards.
Nowadays jQuery is less vital as a normaliser, but still very handy for selecting elements and changing the styling, content, and handling events.
In your example you are doing some things the basic "Vanilla JS" way and some with jQuery. In a few places you have got things a bit mixed up and tried doing it a mix of ways, which won't work...
Referencing an element
by id
If you have an element such as <div id="myDiv"></div> then you can access it using Vanilla JS:
document.getElementById("myDiv");
or jQuery:
$("#myDiv");
Notice that you only provide the real id with getElementById, no hash.
by CSS selector
Another thing that jQuery did, which was amazing at the time, was that it allowed you to access DOM elements using the same selectors as CSS. That is why the jQuery version has a hash (#) because that is the CSS selector for "id=". Nowadays there is a Vanilla JS version of that which is widely supported:
document.querySelector("#myDiv"); // returns a single element
document.querySelectorAll("div"); // returns multiple div elements
Event handling
with jQuery
In your example you have used jQuery to attach some code to the click event of your button.
$("#Ausgabe").on("click",function(){
// blah
});
That's great and attaches your function to be run later when the button is clicked.
with element attributes (the bad way)
However, you have put that in another function which is explicitly called when you click the button, using the old-fashioned onclick attribute.
<input id="Ausgabe" ... onclick="ausgabe()">
Your jQuery event is not initially attached. It only becomes so when the onclick attribute handles the first click. So you have to click the button to attach an event handler to deal with clicking the button. Have you seen the film Inception? You need to make your mind up about which approach to take. You should definitely be attaching to the event rather than using onclick.
Vanilla JS
However, you can also do that with Vanilla JS:
document.getElementById("Ausgabe").addEventListener("click", function() { /* your code goes here */ });
Setting content
Vanilla JS
You have used the Vanilla JS approach for setting content of your element, which is great:
document.getElementById('lname').innerHTML = Namee;
jQuery
But that's another thing that jQuery provides a method for:
$("#lname").html(Namee);
Be consistent
Vanilla JS vs jQuery
To make it easier to both write and read your code, it is better to be consistent. Decide if you are going to use Vanilla JS or jQuery and then stick to it. Although you might use jQuery for some of the more difficult things even when using Vanilla JS (like adding or removing a CSS class name).
Semi-colons
JavaScript instructions are supposed to end with a semi-colon;
You don't always have to do it, and there are people who claim that you shouldn't unless absolutely necessary. But it does make code clearer to read because JavaScript is allowed to split across multiple lines. So the semi-colon tells your reader that you've finished the instruction. My advice is to always use them.
Quotes
JavaScript is flexible on the use of 'single' and "double" quotes. There are different opinions on this, and plenty of arguments for/against each, but it really doesn't matter which. However it is nicer if you stick to one approach:
var string1 = "Stick to one set of quotes";
var string2 = 'else your code will look weird';
var string3 = `even this is allowed in modern JS`;
var string4 = "But this one is BROKEN';
form submit buttons
One more thing, which also harkens back to 'the old days'...
When the world wide web was new there was no JavaScript and web pages were just a little better than plain text. The only interaction was by filling in a form and 'submitting' it back to the server.
If you have a <form> element which contains an <input type="submit"> button then that's what the browser expects to do. If you press that button it will submit the form. Nowadays that's actually quite rare!
If you use that arrangement then you might find that your page doesn't act the way you expect. Therefore it is safer to use non-submit buttons which don't have any special behaviour:
<input type="button" value="My non-submit button">
Good luck and enjoy
That's a lot of advice. Hopefully you can now see where you were going wrong before and have a better understanding of things.
I hope you enjoy coding. It's not scary and if you get properly good at it then you can have a good job in the future. But only go down that route if it really appeals to you. It's actually a horrible job if you spend most of your time on StackOverflow asking for help! ;)
TL;DR
If that was too long and you didn't want to read it then I advise you to not become a developer. Going into the details of how things work is a very important lesson that you never stop learning.

Using the `content` attribute as an HTML Template

I've been trying to use the CSS content property to make somewhat of a "template" for an element of a specific class.
I've tried multiple things. . .
Many places I have seen told me to convert everything to hexadecimal, so I did, until I saw that using hex wrote the litteral characters into the element, instead of evaluating the characters as HTML.
I then tried just litterally entering the characters into the content, and I got the exact same result (this makes it appear as if there is no purpose for the hex, yet thats hard to belive with how many people say there is. . . ).
Is there any way that I can place HTML content into an element using the CSS content attribute?
I've made a JS-Fiddle for this:
And, of course, Stack wants my source:
HTML:
<button id="normal" >Show with normal output</button>
<button id="hex" >Show with Hexadecimal output</button>
<div id="class_changer" ></div>
JS:
function changeClass(evt)
{
class_changer.className = evt.srcElement.id;
}
var class_changer = document.getElementById('class_changer');
var normal = document.getElementById('normal').addEventListener('click', changeClass, true);
var hex = document.getElementById('hex').addEventListener('click', changeClass, true);
And the un-godly long CSS:
.normal::before {
content: '<img alt="Facebook" src="http://cache.addthis.com/icons/v1/thumbs/32x32/facebook.png" />';
}
.hex::before {
content: '\0027\003c\0061\0020\0068\0072\0065\0066\003D\0022\0068\0074\0074\0070\003A\002F\002F\0061\0070\0069\002E\0061\0064\0064\0074\0068\0069\0073\002E\0063\006F\006D\002F\006F\0065\0078\0063\0068\0061\006E\0067\0065\002F\0030\002E\0038\002F\0066\006F\0072\0077\0061\0072\0064\002F\0066\0061\0063\0065\0062\006F\006F\006B\002F\006F\0066\0066\0065\0072\003F\0070\0063\006F\003D\0074\0062\0078\0033\0032\006E\006A\002D\0031\002E\0030\0026\0061\006D\0070\003B\0075\0072\006C\003D\0068\0074\0074\0070\0025\0033\0041\0025\0032\0046\0025\0032\0046\0077\0077\0077\002E\0063\0069\006D\0074\0072\0061\006B\002E\0063\006F\006D\0026\0061\006D\0070\003B\0075\0073\0065\0072\006E\0061\006D\0065\003D\0063\0069\006D\0063\006F\0072\0022\0020\0074\0061\0072\0067\0065\0074\003D\0022\005F\0062\006C\0061\006E\006B\0022\003e\003c\0069\006D\0067\0020\0061\006C\0074\003D\0022\0046\0061\0063\0065\0062\006F\006F\006B\0022\0020\0073\0072\0063\003D\0022\0068\0074\0074\0070\003A\002F\002F\0063\0061\0063\0068\0065\002E\0061\0064\0064\0074\0068\0069\0073\002E\0063\006F\006D\002F\0069\0063\006F\006E\0073\002F\0076\0031\002F\0074\0068\0075\006D\0062\0073\002F\0033\0032\0078\0033\0032\002F\0066\0061\0063\0065\0062\006F\006F\006B\002E\0070\006E\0067\0022\0020\002F\003e\003c\002F\0061\003e';
}
Check it out at JS-Fiddle and see what you can do! Let me know! Thanks everybody!
UPDATE: SOLVED (ish...)
Yes, wierd question sometimes accept wierd answers (like iterating over the DOM...) but if you have a better solution, I'm all ears.
As it turns out, the accepted answers means of evaluating a "CSS template" may be the best means of performing "templating" without the use of third-party libraries or the new <template> tag (that I'm still not sure of) even though it makes my skin crawl (if anyone has a better solution, please post it). Either way, I've updated my JSFiddle, so check it out!
Although, I guess the best answer would be purely making a template as a string in JavaScript, that is, if we are going to be evaluating it later on and pre-pending it to an element. Yea, that would make more sense...
No, this is not possible with plain CSS. However, if you really want to save these templates in CSS, you could iterate over all elements and use
window.getComputedStyle(element, ':before').content
to fetch the content and then prepend/append it to the element. To parse the HTML, you could either use jQuery.parseHTML, new DOMParser().parseFromString or a dummy DOM element. Alternatively, you could also use .innerHTML directly, but I wouldn't recommend that..

How to change the displayed text in label (for Internationalization)

I have an html file that contains something like this
> <label id="remem" for"remem"><input type"checkbox"
> name="remem"/>Test</label>
now Im dealing with i18n and working on translating these words. And what I need to do is Translate the word Test into a different language.
How do I change the label (in my example.."Test" ) programmatically?? What attribute should I deal with?
Thanks!
Give the text inside a <span> tag with id
> <label id="remem" for"remem"><input type"checkbox"
> name="remem"/><span id="rememText">Test</span></label>
Then you can use javascript to manipulate the text.
document.getElementById("rememText").innerHTML = "another language";
#SajithNair's answer certainly works, and for small projects it is quite workable.
For large projects, however, you might find that you need something a bit more organized.
Choice 1
Letting server-side code handle it.
Depending on your server-side framework, this may be the best solution.
Choice 2
Letting a client-side framework handle it.
If you are using something like Knockout, it is a simple matter to decorate your labels with the right bindings and letting Knockout magic happen.
<label for="myfield">
<span data-bind="html: resources.myFieldLabelText"></span>
<input id="myfield" name="myfield">
</label>
Choice 3
If you are not using Knockout, or you decide that making all of your resources observable is too much of a hit, using data-attributes and then swapping out text that way can work.
<label for="myfield">
<span data-label-resource="myfieldResourceKey"></span>
<input id="myfield" name="myfield">
</label>
jQuery/sizzle has a nice engine to handle finding things by data-*, otherwise you can drop back to querySelectorAll. Failing that and you are supporting an ANCIENT browser, you can walk the DOM.
The advantage of using the resource keys like this, rather than doing things ad-hoc on a per-field basis, is that if you re-use a value (say, entry or display, or you use it on multiple pages) you only have one resource that needs translated, as opposed to multiple instances.
try this
<span id="rememText">Test</span>
$("#rememText").innerHtml("string text");
or
<span id="rememText">Test</span>
$("#rememText").val("string text");

Add or minus a variable value on button click?

I'm very new to javascript so please forgive me this if it's actually a crazy simple thing to do, but I've been googling and going through all my reference sites with no luck. What I'm trying to do is display a variable's value and change the value the variable either +1 or -1 when the user clicks the appropriate button - like this.
Can anyone help me? Thanks!
The following is an example you can work with. It's a full HTML page, which you can open in a web-browser to see in action. Copy and paste it into a text-file, which you save as example.html. Open it in notepad or something similar to edit it.
This is just one simple example - there are many ways to do stuff like this. Google around, see examples, and play around with them, and it will make sense, bit by bit.
Though it is old, and not always perfect, the examples at W3C may still be a good place to start if you want to know more.
<html>
<head>
<script type="text/javascript">
var currentValue = 0;
var add = function(valueToAdd){
alert("adding: " + valueToAdd);
currentValue += valueToAdd;
document.getElementById('number').innerHTML = currentValue;
};
</script>
</head>
<body>
<div id="text">Number of eggs:<span id="number">0</span><div>
Plus 1
Minus 1
</body>
</html>
UPDATE: One little addition: If you want a fairly new and good book on Javascript, and want to learn it "correctly", then JavaScript: The Good Parts is probably the book you want. It is not a big book (just under 100 pages if I remember correctly), but gives a nice overview of the language.

Categories

Resources