Friday, August 10, 2012

Tools - Gapfill Code Generator Version 2

Currently in testing mode

For teacher bloggers etc

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 - this is slightly different from the previous version, so please read the instructions

Important warning - this code is offered 'as is'. I've tested it and it seems to be fine, but you use at your own risk and I can't take any responsibility for anything that might go wrong. If you have any problems, please let me know in the comments below.
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.
This new version has been made possible by the perseverance and enthusiasm of Susan at the English in Vancouver blog, who helped me realise some of the limitations of the original program.

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 a unique 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 exercise in your blog must have a unique exercise identifier. You enter this in the Ex Num box. I suggest you use numbers in sequence, but you could use letters or a combination of letters and numbers. You'll be able to see the id of your previous exercise at the bottom of the exercise.
  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. These are in an array, for example ans25=["Tom","Dick","Harry"] etc (where 25 is the exNum)
This change from the previous version means that you can now have the exercises showing in your main list of posts. You no longer need to use the 'insert jump break' function to make readers have to open up the post page to do the exercise. They can do it on your home page or on a page of posts opened by clicking on a label.

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.
Enter this code to open a script section:
<script type="text/javascript">
<!--

//Your Javascript answers code goes inside these tags

// -->
</script>
Now copy in the answer array for this exercise. 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 checkAnsBoxAnswersV2(ansCode,exNum){ 
  var ca=0
  for(var c=0;c<ansCode.length;c++){
    var guess=doSpaces(exNum,c)
    var ans=doAnswers(guess,ansCode[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" 
    } 
  }
  showScoreV2(ansCode,exNum,ca) 
}


function checkAnsBoxInvisibleAnswersScoreV2(ansCode,exNum){
  var ca=0
  for(var c=0;c<ansCode.length;c++){
    var guess=doSpaces(exNum,c)
    var ans=doAnswers(guess,ansCode[c])
    if(ans=="yes"){
      document.getElementById("ex"+exNum+"TickBox"+c).innerHTML=getInvisibleAnswersSign(1)
    document.getElementById("ex"+exNum+"AnsBox"+c).style.color="green"
      document.getElementById("ex"+exNum+"AnsBox"+c).style.fontWeight="bold"
      ca++
    }
    else if(guess==""){
      document.getElementById("ex"+exNum+"TickBox"+c).innerHTML=getInvisibleAnswersSign(3)
    }
    else{
      document.getElementById("ex"+exNum+"TickBox"+c).innerHTML=getInvisibleAnswersSign(2)
    document.getElementById("ex"+exNum+"AnsBox"+c).style.color="red"
      document.getElementById("ex"+exNum+"AnsBox"+c).style.fontWeight="bold"
    }
  }
  showScoreV2(ansCode,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 showScoreV2(ansCode,exNum,ca){
  var qlen=ansCode.length
  var pc=ca/qlen*100
  pc=Math.round(pc)
  var txt="<span style='color:green;font-weight:bold;'>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 showAnsBoxAnswersV2(ansCode,exNum){
  for(var c=0;c<ansCode.length;c++){
  if(document.getElementById("ex"+exNum+"AnsBox"+c).value==ansCode[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=ansCode[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 clearAnsBoxAnswersV2(ansCode,exNum){
  for(var c=0;c<ansCode.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 clearAnsBoxInvisibleAnswersV2(ansCode,exNum){
  for(var c=0;c<ansCode.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=""
}

14 comments:

  1. This is the best page on the entire Internet as far as I'm concerned.

    ReplyDelete
  2. It's certainly amazing! I love it!

    ReplyDelete
  3. Please help me. I did as directed but why JS Code for Click and Drop not working on wordpress theme? Sorry, my english is limited!

    ReplyDelete
  4. Hi Dang,

    Sorry, but Javascript doesn't seem to work on Wordpress unless you download an add-on. I'm afraid I know nothing about Wordpress, but here are some addresses that might be useful:

    Wordpress - general instructions (quite technical)

    Wordpress add-ons Javascript Adder

    Labnol.org - How to Add JavaScript to WordPress Posts and Pages

    Or you could just google "javascript on wordpress"

    ReplyDelete
  5. Thanks for reply, Warsaw Will. I did embebed JS Code in Wordpress is correct because of the top functions is still running but bottom functions is not work. This is in contradictory.
    P/s: I had the help of google to translate, so the grammar may not be accurate :)

    ReplyDelete
  6. Thank you so much for your generosity. I've used the gap fill generator and it has worked wonderfully on my blog (http://e-nglishlanguageonline.blogspot.com.ar/2015/06/phrasal-verbs-with-verb-turn.html).

    ReplyDelete
  7. Thanks for the comment, and for the link. I had a quick look, and it indeed seems to be working fine. It also seems to work quite well from my smartphone, which is something I should be thinking about (I notice that about 18% of my blog visits are from phones or tablets). Unfortunately some of my exercise types don't work so well on smartphones, but this one seems OK.

    ReplyDelete
  8. Hi guys,

    Thanks Will for this great page.

    I've added code for multiple possible answerse:

    If the text has more than one answer, write it as:

    I [can't/cannot/won't] swim.

    And replace this code:

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

    with this code:

    function doAnswers(guess,ans){
    if(ans.indexOf("/")==-1)
    {
    if(guess==ans){
    txt="yes";
    }
    else{
    txt="no";
    }
    }
    else
    {
    var multians = ans.split("/");
    for (var j=0; j<multians.length; j++)
    {
    if(multians[j] === guess) {
    txt = "yes";
    return txt;
    }
    else{
    txt ="no";
    }
    }
    }
    return txt;
    }

    ReplyDelete
  9. Hi there. I'd like to say a big thanks to Will for his code here - I've been using a modified version of it for my website www.ieltstutors.org.

    Cheers Will!

    ReplyDelete
  10. Hi Will,

    I'm back to fixing up my English in Vancouver blog after a somewhat longish break. I am going to change the theme so that it is responsive and I am concerned that the Random English code may not work. For instance, I uploaded a different theme and got this result for a page:
    https://englishinvancouvermess.blogspot.com/2012/08/picking-up-prescriptions-linc-224.html
    I can't remember if I am supposed to put some code in the theme itself to make it work.
    I have used your code so much and I am so thankful for your help. I hope I can get back on track with a new theme.
    https://Englishinvancouver.blogspot.com
    Susan

    ReplyDelete
    Replies
    1. Hi, Susan. I've also been having a long break, and sorry for not answering sooner. I don't think the theme will matter, but I would put everything into the blog post. This way, if there's a problem, it will only affect that post. I've also discovered that if you put JS (and I think CSS) into the head section (in the theme HTML), it won't work on the phone and tablet versions. But when it's all in the blog post, it works fine in the phone version.

      I've just tried this code on my other blog, and it seems to be working fine. One thing, I had to widen the tdNum to 30px, as it wasn't showing properly.

      Will's English Tips

      Delete
  11. All is working perfectly. Thanks for your input, Will. Hope you had a great break. Cheers!

    ReplyDelete