...

View Full Version : Button for incremental array?



meridian
06-27-2012, 09:46 AM
Hi there
I am still new to JavaScript and am trying to work out a small script that functions as flashcards to learn Japanese vocab. The code below shows pretty much what I want to do, however I wish to make the "next" button repeat the script for the next pair of words in the 2 arrays (ie Japanese and it's meaning in English. Any assistance would be greatly appreciated. :confused:

[CODE]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Japanese Vocab</title>

</head>
<body>

<h1>Japanese Vocab</h1>
<p id="japanese"></p>
<p id="english">&nbsp;</p>

<button onclick="showEnglish()">Answer</button>
<button onclick="nextWord()">Next word</button>

<script type="text/javascript">
var japanese=new Array("食べる","読む","行く");
var english=new Array("to eat","to read","to go");
document.getElementById("japanese").innerHTML=japanese[0];

function showEnglish()
{
document.getElementById("english").innerHTML=english[0];
}

</script>

</body>
</html>
[CODE]

vwphillips
06-27-2012, 12:20 PM
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Japanese Vocab</title>

</head>
<body>

<h1>Japanese Vocab</h1>
<p id="japanese"></p>
<p id="english">&nbsp;</p>

<button onclick="showEnglish()">Answer</button>
<button onclick="nextWord()">Next word</button>

<script type="text/javascript">
var japanese=new Array("1","2","3");
var english=new Array("to eat","to read","to go");
var cnt=0;

document.getElementById("japanese").innerHTML=japanese[cnt];

function showEnglish(){
document.getElementById("english").innerHTML=english[cnt];
}

function nextWord(){
cnt=++cnt%japanese.length;
document.getElementById("japanese").innerHTML=japanese[cnt];
document.getElementById("english").innerHTML='';
}

</script>

</body>
</html>

Dormilich
06-27-2012, 12:34 PM
of course it somewhat depends on how modern it may be. e.g. Mozilla supports Iterators (https://developer.mozilla.org/en/JavaScript/Guide/Iterators_and_Generators), which is (from the sound of it) best suited. however, it can also be done in plain old JS.

// only tested in FF
var it = Iterator([
{jp: "食べる", en: "eat"},
{jp: "読む", en: "read"},
{jp: "行く", en: "walk"},
]);

var loop = function()
{
try {
var obj = it.next()[1];
this.textContent = obj.en + " => " + obj.jp;
}
catch (e) {
alert("end of iteration");
}
}
// attached to a button
document.getElementById("test").addEventListener("click", loop, true);

meridian
06-27-2012, 02:49 PM
Thanks heaps vwphillips & Dormilich for such a quick response
That really helps. The counter variable was exactly what I was looking for.
The iterators solution was a bit over my head but certainly gives me something to start working on. The Mozilla link was also quite helpful.
Cheers. Much appreciated :)

meridian
06-28-2012, 01:09 AM
Actually I tried using the same principle on a previous word button but I seem to get an undefined error. I guess I'm still missing something.



<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Japanese Vocab</title>

</head>
<body>

<h1>Japanese Vocab</h1>
<p id="japanese"></p>
<p id="english">&nbsp;</p>

<button onclick="prevWord()">Previous word</button>
<button onclick="showEnglish()">Answer</button>
<button onclick="nextWord()">Next word</button>

<script type="text/javascript">
var japanese=new Array("食べる","読む","行く");
var english=new Array("to eat","to read","to go");
var cnt=0;

document.getElementById("japanese").innerHTML=japanese[cnt];

function showEnglish()
{
document.getElementById("english").innerHTML=english[cnt];

}

function nextWord()
{
cnt=++cnt%japanese.length;
document.getElementById("japanese").innerHTML=japanese[cnt];
document.getElementById("english").innerHTML='&nbsp;';
}
function prevWord()
{
cnt=--cnt%japanese.length;
document.getElementById("japanese").innerHTML=japanese[cnt];
document.getElementById("english").innerHTML='&nbsp;';
}
</script>

</body>
</html>

Old Pedant
06-28-2012, 02:09 AM
This doesn't work:


cnt=--cnt%japanese.length;

The % (modulo) operator works with negative values, but the values *ARE* still negative. So of course they are out of range of the array elements.

Easy fix:


cnt = ( cnt + japanese.length - 1 ) % japanese.length;


But there's an even easier way:


<button onclick="nextWord(1)">Previous word</button>
<button onclick="showEnglish()">Answer</button>
<button onclick="nextWord(-1)">Next word</button>

<script type="text/javascript">
var japanese=new Array("食べる","読む","行く");
var english=new Array("to eat","to read","to go");
var cnt=0;

function showEnglish()
{
document.getElementById("english").innerHTML=english[cnt];
}
function nextWord( moveBy )
{
cnt = ( cnt + japanese.length + moveBy ) % japanese.length;
document.getElementById("japanese").innerHTML=japanese[cnt];
document.getElementById("english").innerHTML='&nbsp;';
}
nextWord(0); // get it started
</script>

Old Pedant
06-28-2012, 02:14 AM
But you know, it would be better to keep the words paired, rather than depending on parallel arrays that could easily get out of sync. So:


<button onclick="nextWord(1)">Previous word</button>
<button onclick="showEnglish()">Answer</button>
<button onclick="nextWord(-1)">Next word</button>

<script type="text/javascript">
var words = [
["食べる", "to eat"],
["読む", "to read"],
["行く", "to go"]
];
var wordCount = words.length;
var cnt=0;

function showEnglish()
{
document.getElementById("english").innerHTML = words[cnt][1];
}
function nextWord( moveBy )
{
cnt = ( cnt + wordCount + moveBy ) % wordCount;
document.getElementById("japanese").innerHTML = words[cnt][0]
document.getElementById("english").innerHTML='&nbsp;';
}
nextWord(0); // get it started
</script>

meridian
06-28-2012, 05:04 AM
Thanks Old Pedant for your advice. I can see your point about keeping the pairs together. This is probably a good idea since I could potentially be putting hundreds of words into the script and that way would make it easier to deal with.
I am really glad to have discovered this forum. I was just trying to learn this stuff solo but kept getting stuck. Thanks for your help guys.:thumbsup:

Old Pedant
06-28-2012, 09:17 PM
I had the previous and next buttons backwards, as I'm sure you discovered.

It should be

<button onclick="nextWord(-1)">Previous word</button>
<button onclick="showEnglish()">Answer</button>
<button onclick="nextWord(1)">Next word</button>

meridian
06-29-2012, 02:19 AM
Ahh. I was wondering why it was behaving a bit odd there.
Last night I was studying your counter and trying to understand how it was working. I'm still trying to understand how the first click of the previous word button gets the ctn value of 2. I can see how the rest is calculated (see comments in code below). I also added some lines to display the values with each click. Just to clarify, "moveBy" is just an arbitrary variable isn't it and not a method

Thanks for your help



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Japanese Vocab</title>
</head>

<body>

<h1>Japanese Vocab</h1>
<p id="japanese"></p>
<p id="english">&nbsp;</p>

<button onclick="nextWord(-1)">Previous word</button>
<button onclick="showEnglish()">Answer</button>
<button onclick="nextWord(1)">Next word</button>

<p id="counter">&nbsp;</p>
<p id="wordCount">&nbsp;</p>
<p id="moveBy">&nbsp;</p>



<script type="text/javascript">
var words =
[
["食べる", "to eat"], // 0
["読む", "to read"], // 1
["行く", "to go"], // 2

];
var wordCount = words.length;
var cnt=0;

function showEnglish()
{
document.getElementById("english").innerHTML = words[cnt][1];
}
function nextWord( moveBy )
cnt = ( cnt + wordCount + moveBy ) % wordCount;
/* Next word
0 time cnt = (0 + 3 + 0) =3 /3 = 0 remainder
1st time cnt = (0 + 3 + 1) =4 /3 = 1 remainder
2nd time cnt = (1 + 3 + 1) =5 /3 = 2 remainder
Previous word
1st time cnt = (0 + 3 + -1) =2???? /3 = 2 remainder
2nd time cnt = (2 + 3 + -1) =4 /3 = 1 remainder
3nd time cnt = (1 + 3 + -1) =3 /3 = 0 remainder

*/
document.getElementById("japanese").innerHTML = words[cnt][0]
document.getElementById("english").innerHTML='&nbsp;';

document.getElementById("counter").innerHTML="counter = "+ cnt;
document.getElementById("wordCount").innerHTML="wordCount = " + wordCount;
document.getElementById("moveBy").innerHTML="moveBy = " + moveBy;

}
nextWord(0); // gets it started

</script>
</body>
</html>

Old Pedant
06-29-2012, 03:30 AM
Yes on all counts.

And you correctly showed why adding the wordCount fixes any problems with going backwards. It causes you to "wrap around" from 0 to the last element. It's not needed when going forward, of course, but it doesn't hurt at all. So by having it there the code works for both directions.

meridian
06-29-2012, 07:21 AM
Thanks Old Pedant. Forgive my ignorance but I still am trying to understand how the calculation works for the previous button. When the page loads cnt = 0, when previous is clicked ctn=2.
The inputs for this I believe are: (0 + 3 + -1) % 3.
Math is not my strong point but these inputs don't seem to equal 2. May I ask how this calculation is performed or are these inputs wrong. Sorry.
:confused:

Philip M
06-29-2012, 07:28 AM
Thanks Old Pedant. Forgive my ignorance but I still am trying to understand how the calculation works for the previous button. When the page loads cnt = 0, when previous is clicked ctn=2.
The inputs for this I believe are: (0 + 3 + -1) % 3.
Math is not my strong point but these inputs don't seem to equal 2. May I ask how this calculation is performed or are these inputs wrong. Sorry.
:confused:

0 + 3 + - 1 = 2

2 modulo 3 = 2. i.e the remainder when 2 is divided by 3, which is 0 times with 2 over. OK?

meridian
06-29-2012, 08:07 AM
Ok. I see now. I think I was thrown out by the fact that the second number was larger than the first (and couldn't be divided into it). That makes sense now. Thanks for spending the time to explain it.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum