Sunday, May 13, 2012

Tools - Interactive Gapfill Exercise Code Generator


For teacher bloggers etc

This has now been superseded by Version 2 which has been well tried and tested and I recommend you use it rather than this one.

With this generator you can make interactive gapfill exercises for your blog or web page. If you want to make an exercise without the interactivity, you can use just the HTML (without the buttons) and the CSS. You could also use this for generating worksheets, but you'd be better going to my Multi-function gapfill generator
  1. Use the program to automatically generate a gapfill exercise
  2. The program will also generate the HTML and Javascript code you need for this particular exercise and it's answers
  3. Copy the rest of the Javascript and CSS code into your blog post or web page
Note - I've made some important changes to the instructions since this was first published.

Important warning - this code is offered 'as is'. I've tested it and it seems to be fine, but you use it at your own risk and I can't take any responsibility for anything that might go wrong.
Feedback - If you have any problems, please let me know in the comments below. If you've already published, let me know the web address of the page, and I'll see if I can diagnose the problem. In fact if you publish successfully, it would still be nice to have a link.
Strong recommendation - I strongly recommend you try this out on a text editor (EG Wordpad - see 'How do I make a web page version' below) before putting it on your blog. I do everything in a text editor first and try it out on my browser before publishing.

A. First create the exercise

You can choose yourself which words to gap, or for an instant exercise, you can use the automatic gap maker. This makes random gaps or takes away selected groups of words, for example: articles.

How to use - where you see ? mouse over for more details.

Probably the best way to see how it works is to play around with the examples and all the options for a few minutes.

Some general comments

There are really three types of exercise:
  1. lists of questions with one gap per question
  2. lists of questions with more than one gap per question
  3. texts with more than one gap per paragraph
The main things to consider here are numbering and the tick facility. Do you want paragraphs numbered, both questions and gaps numbered etc - play around with the numbering to see what works best.
If you to use the tick facility, for single gap questions the best position is line-end, and for multiple gaps or texts, 'After gap' or 'None'. Again try generating an exercise, press 'Show', then 'Check' and see what works best.
1. Enter the title and instructions (optional): ?
2. Enter a list of questions or a text ? or:
3. Give the exercise an Ex Num: ?
4. Make the gaps, manually ?
or automatically
Show details
5. Add required treatment to gapwords or text (optional) Show details
6. Adding an example at the beginning (optional) Show details
7. Fine tuning (optional) - reset to
Title: Position
Numbering: Questions (Paras) Gaps Both Neither ?
Clickable: ? Tick: Show details
Word box: Middots ? Repeats ? Lower case ?
Select: Gap width ? Line height ? font ?
8. Select gap word option Show details and

Your exercise will appear here

B. Now we'll look at the code

This is in four parts
  1. The HTML code - consisting of:
    • Optional title
    • Top word box, if wanted
    • The main exercise
    • The code for the buttons
  2. The Javascript program code
  3. The Javascript answer code
  4. The CSS Code

Main principles

  1. Ex Num - You can put as many exercises as you like on a page, but each must have a unique exercise number. You enter this in the Ex Num box (default - 1)
  2. Gaps - each gap has a unique ID number which includes the Ex Num. This is generated by the program and is the basis of how the whole thing works
  3. Variables and Arrays - if using the clickable version you need to declare a universal variable
    clickedWord=""
    the Javascript is built mainly on arrays. The most important to know concerns the answers. There is an overall array which must be declared before the answers
    ansA=[]
    and then on a new line each set of answers consists of a subarray of ansA
    ansA[1]=["Tom","Dick","Harry"] etc

Important! - The overall arrays ansA=[ ] and and clickedWord must be declared once only.

This means that you should not have the exercises showing in your main list of posts. You need to use the 'insert jump break' function so that readers have to open up the post page to do the exercise. Otherwise the buttons will work in the individual post page, but not in the list of posts.
If you really want to have exercises showing on the post lists, then declare the overall array ansA=[ ] in a Javascript section in your template, and not in the posts.

How do I make a web page version? - Show instructions

As far as blogs are concerned, I only know the procedure with Blogger. Sorry! But I imagine it's pretty similar on other blogging platforms.

Where do I put the code in Blogger?

If you're not familiar with using code, it would be worth looking at the instructions for a web page above before reading this.

Important! - Please click on this link and read these instructions carefully before putting anything into Blogger - Show instructions for Blogger

HTML Code, to go in your main post

In each box - Right Click, Select All and Copy

HTML Title code

HTML Wordbox code

HTML Main exercise code

HTML Buttons code

CSS Code

This can go in the Head section in a web page, after 'title'. In Blogger enter it as the first item on the blog page, before the Javascript and HTML code.

Main points, if you want to change the style

If you want to change the CSS, these are the relevant class names:
  • The title is .instrC
  • The top word box is .wordbox
  • The words in the top word box are .optionWord
  • The question numbers are .tdNumC
  • The gap boxes are .textBoxC
  • The buttons are .buttonC
<style type="text/css">
<!-- 

.instrC{
color:gray;
font-weight:bold;
}

.wordbox{
border:solid gray 2px;
margin:10px auto;
padding:3px 5px;
line-height:1.5;
font-weight:bold;
color:gray;
padding:4px 10px;
border-radius:15px;
-moz-border-radius:15px;
-webkit-border-radius:15px;
-o-border-radius:15px;
box-shadow:2px 2px 7px #333;
-moz-box-shadow:2px 2px 7px #333;
-webkit-box-shadow:2px 2px 7px #333;
-o-box-shadow:2px 2px 7px #333;
text-align:center;
}

.optionWord{
color:gray;
font-weight:bold;
}

.optionWord a{
color:gray;
text-decoration:none;
}

.optionWord a:hover{
color:black;
text-decoration:none;
}

.tdNumC{
padding:0 7px 0 0px;
color:gray;
font-weight:bold;
vertical-align:top;
}

.buttonC{
background:gray;
color:white;
padding:2px 3px;
font-weight:bold;
-moz-border-radius:5px;
-webkit-border-radius:5px;
-o-border-radius:5px;
-moz-box-shadow:1px 1px 5px #333;
-webkit-box-shadow:1px 1px 5px #333;
-o-box-shadow:1px 1px 5px #333;
margin:0 2px;
}

.textBoxC{
border:none;
border-bottom:1px dotted gray;
}


 -->
</style>

Javascript answers code

The answers code should go into a Javascript section on the page itself. If using Blogger, the answers code should go in a Javascript section at the top of your post page. First you need to declare the universal variables.
Important! - The overall arrays ansA=[ ] and clickedWord must be declared once only. This means that you should not have the exercises showing in your main list of posts. You need to use the 'insert jump break' function so that readers have to open up the post page to do the exercise. Otherwise the buttons will work in the individual post page, but not in the list of posts.
If you really want to have exercises showing on the post lists, then declare the overall arrays ansA=[ ] and clickedWord in a Javascript section in your template, and not in the posts. But I don't really recommend this.
<script type="text/javascript">
<!--

var clickedWord=""
var ansA=[]

// -->
</script>
Now copy in the answer array for this exercise on a new line after var ansA=[ ]. If you have more than one exercise, keep adding the answer arrays on new lines:
Note - If you see something like &#8217; or &# followed by any other four figure number and a semicolon in the answers code, for some reason things like asterisks and inverted commas have been converted into base code, although this shouldn't happen. You do not want this in the JS answers, so you'll need to replace these with their original signs - for example &#8217; is an asterisk.

Javascript program code

Now copy the rest of the Javascript. It can go in the Body section or in the Head section on a web page, or in the 'New Post' page on Blogger.

JS opening and closing tags

If you haven't already got a Javascript section, you'll need these opening and closing tags
<script type="text/javascript">
<!--

//Your Javascript code all goes inside these tags

// -->
</script>
Now copy all the Javascript, including the headers and paste into the Javascript section.

// JS Code for checking the answers

function checkAnsBoxAnswers(exNum){ 
  var ca=0
  for(var c=0;c<ansA[exNum].length;c++){
    var guess=doSpaces(exNum,c)
    var ans=doAnswers(guess,ansA[exNum][c])
    if(ans=="yes"){
      document.getElementById("ex"+exNum+"AnsBox"+c).style.color="green"
      document.getElementById("ex"+exNum+"AnsBox"+c).style.fontWeight="bold"
      ca++
    }
    else{
      document.getElementById("ex"+exNum+"AnsBox"+c).style.color="red" 
    } 
  }
  showScore(exNum,ca) 
}


function checkAnsBoxInvisibleAnswersScore(exNum){
  var ca=0
  for(var c=0;c<ansA[exNum].length;c++){
    var guess = document.getElementById("ex"+exNum+"AnsBox"+c).value;
    var ans=doAnswers(guess,ansA[exNum][c])
    if(ans=="yes"){
      document.getElementById("ex"+exNum+"TickBox"+c).innerHTML=getInvisibleAnswersSign(1)
      ca++
    }
    else if(guess==""){
      document.getElementById("ex"+exNum+"TickBox"+c).innerHTML=getInvisibleAnswersSign(3)
    }
    else{
      document.getElementById("ex"+exNum+"TickBox"+c).innerHTML=getInvisibleAnswersSign(2)
    }
  }
  showScore(exNum,ca) 
}


function doAnswers(guess,ans){
  if(guess==ans){
    txt="yes"
  }
  else{
    txt="no"
  }
  return txt
}


function getInvisibleAnswersSign(x){
  if(x==1){
    var txt='<span style="color:green;font-weight:bold;">Y</span>'
  }
  else if(x==2){ 
    var txt='<span style="font-size: 100%;color:red;font-weight:bold;">X</span>'
  }
  else if(x==3){ 
    var txt='<span style="font-size: 100%;color:orange;font-weight:bold;">?</span>'
  }
  return txt  
}


function showScore(exNum,ca){
  var qlen=ansA[exNum].length
  var pc=ca/qlen*100
  pc=Math.round(pc)
  var txt="<span class='instrC'>You have scored "+pc+" percent ( "+ca+" / "+qlen+" )</span>"
  document.getElementById("messageArea"+exNum).innerHTML=txt
}


function doSpaces(exNum,qNum){
  var txt=document.getElementById("ex"+exNum+"AnsBox"+qNum).value
  if(txt.charAt(txt.length-1)==" "){
    txt=txt.slice(0,txt.length-1)
    document.getElementById("ex"+exNum+"AnsBox"+qNum).value=txt
  }
  return txt
}

// JS Code for showing the answers

function showAnsBoxAnswers(exNum){
  for(var c=0;c<ansA[exNum].length;c++){
  if(document.getElementById("ex"+exNum+"AnsBox"+c).value==ansA[exNum][c]){
    document.getElementById("ex"+exNum+"AnsBox"+c).style.color="green"
    document.getElementById("ex"+exNum+"AnsBox"+c).style.fontWeight="bold"
  }
  else{
    document.getElementById("ex"+exNum+"AnsBox"+c).value=ansA[exNum][c]
    document.getElementById("ex"+exNum+"AnsBox"+c).style.color="red"
    document.getElementById("ex"+exNum+"AnsBox"+c).style.fontWeight="bold"
    }
  }
}

// JS Code for clearing the answers

function clearAnsBoxAnswers(exNum){
  for(var c=0;c<ansA[exNum].length;c++){
  document.getElementById("ex"+exNum+"AnsBox"+c).value=""
  document.getElementById("ex"+exNum+"AnsBox"+c).style.color="black"
  document.getElementById("ex"+exNum+"AnsBox"+c).style.fontWeight="normal"
  }
  clearMessageArea(exNum)
}


function clearAnsBoxInvisibleAnswers(exNum){
  for(var c=0;c<ansA[exNum].length;c++){
    document.getElementById("ex"+exNum+"AnsBox"+c).value=""
    document.getElementById("ex"+exNum+"AnsBox"+c).style.color="black"
    document.getElementById("ex"+exNum+"AnsBox"+c).style.fontWeight="normal"
    document.getElementById("ex"+exNum+"TickBox"+c).innerHTML=""
  }
  clearMessageArea(exNum)
}

function clearMessageArea(exNum){
  document.getElementById("messageArea"+exNum).innerHTML=""
}

// Optional JS Code for Click and Drop

function makeClickedWord(exNum,x){
  var txt=document.getElementById("ex"+exNum+"Word"+x).innerHTML
  clickedWord=txt
}


function enterClickedWord(exNum,x){
  var txt=clickedWord
  document.getElementById("ex"+exNum+"AnsBox"+x).value=txt
  clickedWord=""
}


function enterClickedWordCap(exNum,x){
  var txt=clickedWord
  var firstLetter=txt.slice(0,1)
  firstLetter=firstLetter.toUpperCase()
  var rest=txt.slice(1,txt.length)
  txt=firstLetter+rest
  document.getElementById("ex"+exNum+"AnsBox"+x).value=txt
  clickedWord=""
}


16 comments:

  1. I'm having trouble with a second post. I gave it a different ID number, but it comes out as the initial quiz I made even though all the HTML is different.

    See post: http://englishinvancouver.blogspot.ca/2012/05/function-checkansboxanswersexnum-var.html

    I'm wondering if you know why. I hope this is not too much trouble for you.

    ReplyDelete
  2. If you do a view source on the page, you'll see that I've done a gap fill for the story, but it now isn't coming out at all. Before it was coming out as the first quiz I did. I wrote a note to students in red and the "Complimenting Quiz" disappeared. Is it because I don't have a title and instructions?

    ReplyDelete
  3. Improvement, but buttons are not working.

    ReplyDelete
  4. Buttons working. Just wonder now why video is so far away from text. Working on this. Thanks again for your awesome post. It is wonderful to be able to post self-correcting quizes for students. I really appreciate your help.

    ReplyDelete
  5. The video thing is easy: you've got three line breaks (
    ) between the video and the exercise. This could have been done automatically by Blogger, especially if you use the WYSIWYG editor. In my Post Options, I've unchecked 'Press Enter for line breaks'. Also I make it Show HTML Literally.

    But what puzzles me is where you're getting these entity numbers (&#8 etc) in the exercise answers. I've tried it on both IE and Firefox and they don't show up like this in the boxes. Are you taking the code from the boxes and not from a Page View? In the meantime I would change them in your code to apostrophes etc.

    Also you've missed off the MessageArea from the buttons code, so it's not showing the score.

    I'm afraid I can't really do anything more till Saturday.

    ReplyDelete
  6. @Susan - I've put some important new info in the instructions, which hopefully should solve your problems. This is a steep learning curve for me too. Your latest one works on its own page but not in the blog list. I think this is because ansA=[] should only be declared once. But if exercises are visible in the list, ansA is declared each time. So I always 'insert jump break' on the editor which shows 'Read more' before the main text with the exercises. This puts everything away on a separate page. If you contact me at will dot randomidea at sign gmail dot com, I can go into more detail.

    ReplyDelete
  7. Hi Will,

    Thanks for posting the new instructions. I will read and try what you suggest and will contact you for more info as you suggest. It's sunny here today and will rain tomorrow. So, I'm going to go out and enjoy the weather for a bit. I have to say though, that I am really enjoying working on the blog and making some useful learning exercises for my students. Thanks so much for your help.

    ReplyDelete
  8. Fixed the inconsistency. Scoring for Shopping for Pants now works on its title page as well!

    ReplyDelete
  9. Hi there. This is a magical resource - I've been looking for something like this for ages. I did read the instructions/blurb (promise), but do you have any feedback on making this work on wordpress?

    I have a fully functioning htm file but it won't behave in a post itself.

    On a different note is there any chance of getting you to post something on my site? I'm just getting back into business and I'm looking at a mini-project where I get different teachers to do things with idioms.

    The prototype is here (feel free to delete the link - this is just the only way I can contact you!)http://www.dcielts.com/idioms/getting-your-head-around-idioms/. At the mo I am playing around with different templates for making intuitive online and paper based exercises from it. (I've got myself stuck on hot potatoes for my daily word exercises). The idea is to build up a database of different teachers doing different things with idioms.

    In any event huge respect for your site. Brilliant. Just wish i hadn't painted myself into the IELTS box.

    ReplyDelete
  10. I completely agree. This is a
    magical resource and the site is brilliant!.
    I too have huge respect for the site and for the person who created it--consistenly helpful and supportive in assisting me with my site and these super cool interactive blog exercises. Thanks so much Will! Version 2 works like a dream--just tried it.

    ReplyDelete
  11. Thanks for that Damian, and especially for the really nice comment on your own site. I'd noticed people coming from your site earlier today, and checked you out.

    I've just loaded a new improved version of this generator at http://random-idea-english.blogspot.com/2012/08/tools-gapfill-code-generator-version-2.html. It hopefully irons out some of the problems that Susan had come up against. It's in test mode till Susan has had a chance to put it through its paces, but it seems to work OK.

    I'm afraid I know nothing about how Wordpress works. It took me a bit of time to work out Blogger's little quirks.

    Thanks for the invitation. I'm a little tied up at the moment, but I'll take a look at what you've done so far. By the way, you can contact me at will dot randomidea at sign gmail dot com.

    ReplyDelete
  12. @Damian - it seems that if you have a Wordpress.com site, you're not allowed Javascript - http://en.support.wordpress.com/code/

    It's apparently possible on Wordpress.org but it looks a bit complicated - http://codex.wordpress.org/Using_Javascript

    I think the standard free blogs are .com

    ReplyDelete
  13. Hi Will,

    How are you? I'm starting a new blog and am using your generator again, but I can't get it to work. I've noticed you've added ansA as a new variable and have incorporated this, but even though it seems that I've meticulously followed your instructions, it is not working. Do not have your email because I had to change email accounts. Please write back. Would really like to use this generator again. Have spent the entire dayi working on this.

    Susan

    ReplyDelete
  14. Hi, this is the old version, which I changed after your original input. I've just tested this (see latest post) and it works fine, but will give problems on multiple posts showing on your home page.

    You need to go to Version 2 (link above), which is the one you were using before.

    If you have any problems with that, just post a comment. All the best.

    ReplyDelete