I am creating a simple numeracy game where by there is a grid populated with numbers. The numbers are hidden and when the game is run the grid space is highlighted. A div on the side produces a sum to help the user get the correct answer. The user then clicks the corresponding numbers that animate into position and signal whether they are right or wrong.
The problem I am having is that when the program is run a trigger('click') function should select an area at random in the grid and apply the class .spellword. This will highlight the area purple, indicating where to place an answer.
At the moment when I run the program nothing happens and I do not know why. I have made the same game but with words and it worked fine.
Here is the function for the button
$('.minibutton').click(function() {
$('.minibutton').prop('disabled', false);
$('.picstyle').show();
$('td').removeClass('spellword');
var r = rndWord;
while (r == rndWord) {
rndWord = Math.floor(Math.random() * (listOfWords.length));
}
$('td[data-word="' + listOfWords[rndWord].name + '"]').addClass('spellword');
$('td[data-word=' + word + ']').removeClass('wordglow').removeClass('wordglow4').removeClass('wordglow3').css('color', 'transparent');
var noExist = $('td[data-word=' + listOfWords[rndWord].name + ']').hasClass('wordglow2');
if (noExist) {
$('.minibutton').click();
} else {
$('.picstyle').text(sum);
}
}).trigger("click");
Fiddle: http://jsfiddle.net/ZAfVZ/33/
Data-letter and data-word are blank on every table cell. That's why your code is failing.
Edit: see this JSFiddle for a working example. When assigning data-letter to your table cell you were missing a string cast (word.toString()[k]). You still have a handful of table cells with no answer and no data-word - is this intentional?
Related
I am making a simple math game in adobe captivate. When the slide loads two random numbers are generated. The user enters a sum in a text entry box and submits their answer. If the user's answer matches the correct sum they get a new problem.
All of this works, but I can't figure out how to clear their answer out of the text entry box when they submit it.
My code is below:
var sum = window.cpAPIInterface.getVariableValue('userAnswer');
var rand1 = window.cpAPIInterface.getVariableValue('rand1');
var rand2 = window.cpAPIInterface.getVariableValue('rand2');
var corrSum = rand1 + rand2;
if (sum == corrSum ) {
alert('great jobs');
var rand1 = Math.floor((Math.random() * 20) + 1);
var rand2 = Math.floor((Math.random() * 20) + 1);}
else {alert('try again'); }
It can be done using jQuery. Not sure what the instance names of your text entry boxes are, but say you have a TEB you've named "InputText", Captivate will then output a textfield with the ID of "InputText_inputfield". You can then access this text field and clear its contents with the following jQuery code:
$("#InputText_inputfield").val("");
If it's the first text field in a series and you want it to have focus, use the following jQuery code:
$("#InputText_inputfield").val("").focus();
It's as simple as adding the above code to the "Execute JavaScript" Script_Window, for your 'clear' button.
The code below is to appear additional 2 textbox and 1 textarea everytime i click a button.
var x=1;
var count=0;
$('body').on('click','#add',function()
{
if(count < 6)
{
$('#div').append("<div class='line'><input type='text' name = 'txta"+x+ "' id='txta"+ x +"'><span class =wordtab></span> <textarea rows='9' onkeyup='countChar2(this)' cols='50' name = 'txtc"+x+ "' id='txtc"+ x +"'></textarea> <span class =wordtab></span><input style = 'width:50px' type='text' name = 'txtb"+x+"' id='txtb"+ x +"'><span class =wordtab></span><button class='delete' value ='Delete Row'>Delete Row</button></div><div style='margin-left: 750px' id='charNum" + x + "'></div>");
count++;
x++;
}
else
alert("Maximum 6 Skills");
});
$('body').on('click','.delete',function()
{
$(this).closest('.line').remove();
count--;
});
The below function is the code that i currently have (which i know its wrong) to put in a counter for every textarea that i added in.
function countChar2(val)
{
var len = val.value.length;
if (len >= 200)
{
val.value = val.value.substring(0, 500);
}
else
{
var id = "charNum" + x;
$(id).text((200 - len)+" words left");
}
};
So my goal is that everytime i click on the add row and start typing on the textarea, it will show the word count for that particular texarea just right below the textarea box.
To get a unique counter added to each textarea, you could append another div to the textarea with a specific class e.g.
Set the HTML structure to something such as:
<textarea></textarea><div class='text-count-area'>Word Count: 0</div>
Add the following JS at the point where each textarea is added e.g. just before 'count++' in your original code (note: this is not the most efficient way of doing this, but this will work easily with your current code):
// Bind the text area to the keyup event
$("textarea").on('keyup', function(val) {
// Simple word count
var words = this.value.match(/\S+/g).length;
// Write the word count to the immediate text-count-area div afterwards
$(this).next(".text-count-area").text("Text count" + words);
});
The word count is kept simple here for readability, but the logic from other answers (highlighted in the comments) could be implemented at this stage.
A JS Fiddle demo of this working is here.
Let see your example:
You add each div by .append method, it's correct
You count input symbols by onkeyup event, it's correct too
All you need is update your countChar2 function because this function has wrong body in that lines:
var id = "charNum" + x;
$(id).text((200 - len)+" words left");
First of all: try to debug your code via developer tools in your favorite browser with breaks in that lines. This step can give your much more and quickly info than posting question in stackoverflow :)
For onkeyup event you should use link to this object instead of id inside your function:
$(val).parent().find('.words-left').val((200 - len));
This line uses val as a link to textarea object in just appended line. .parent() gives you access to wrapper and find() finds input for words left field. (I've added '.words-left' class to your input, see my fiddler bellow). And this code works in stage of your just added line.
Your code of $('body').click() should be executed, when document is fully loaded and DOM ready. But all your ids that you will create in future doesn't appends that DOM. That's why your delete function works properly - that function uses class selector instead of id.
Proposed by me code doesn't uses id selector because it is not needed. All that needs to me - link to current object in new line, val - what I need for that operation.
BTW: When you implement function that works with objects, such as onkeyup='countChar2(this)', better way to use object as passed variable - var countChar = function(obj) {. Because val is using for scalar values in common way.
You can check my code here https://jsfiddle.net/jo0cd3yr/1/
Problem
Suppose that in the backend of my Web application I have a generic string of letters:
seq = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
and an array of positions in such a string:
pos = [(0, 2), (4, 8)]
I need to render this sequence in the frontend by splitting it every n characters. Then when a user clicks a button I need to highlight the sequence between two parameters (taken from pos) for which the button refers to.
My solution
I solve this by implementing a Javascript function formatSequence which splits seq every n characters and iterates through the pos array in order to wrap each substring inside a span tag. The result is something like this:
<pre>
<span class="A">AA</span>AA<span class="B">A</span>
<span class="B">AAA</span>AA
AAAAA
</pre>
When the user clicks the button referring to the class A I simply change the CSS background rule for class A.
It works :) But the function formatSequence is way too complicated imho. It was a pain dealing with multiple lines. I prefer not posting the code since I am looking for other approaches not changing the code of such function.
A better solution?
I think that a (better?) solution would be to implement a function that given two parameters start and end it dynamically highlights the text between them. But it appears to be even more complicated than the previous one (remember that the sequence must be split every n characters and thus the highlight must be multilines).
Any suggestions? Better approach to solve this?
One simple solution would be just to print the full seq multiple times into the HTML and hide every row you don't need at the time. When a user clicks on a button, another row would be displayed (and the first one would be hidden).
HTML:
<div class="rows"></div>
<div class="buttons"></div>
JavaScript (depending on jQuery):
(function generateRowsAndButtons() {
var sequence = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
var position = [ [0,2], [4,8] ];
var $rows = $('.rows');
var $buttons = $('.buttons');
for(var i = 0; i < position.length; i++) {
if(position[i].length !== 2 || position[i][0] > position[i][1]) {
console.log("every position array needs exactly two values with the second larger than the first one");
continue;
}
// the index is used for mapping the button the highlight position
var row = '<div class="row" data-index="' + i + '" style="display: none;">';
// you should add some checks here, if position larger then the length of the string to avoid some misbehaviors. this is of course only necessary if you aren't validating the values on another place.
row += sequence.substring(0, position[i][0]);
row += '<span class="highlighted">';
row += sequence.substring(position[i][0], position[i][1]);
row += '</span>';
row += sequence.substring(position[i][1]);
row += '</div>';
var $row = $(row);
$rows.append($row);
// a button needs the index to find the link the highlighted value
var $button = $('<button data-index="' + i + '">' + position[i] + '</button>');
$buttons.append($button);
}
$buttons.find('button').click(function() {
var index = $(this).data('index');
// hide every row, except the one with the correct index
$rows.find('.row').hide().filter('[data-index="' + index + '"]').show();
});
})();
CSS:
.row .highlighted {
background: yellow;
}
Here is a jsFiddle: https://jsfiddle.net/y8uoou1L/2
I want to write a Greasemonkey script that will change the color of the text on any page while leaving the structure as it is. I would like to change the first 10 visible characters to be red, the next 10 to be blue, the next to be red again and so on.
I see two possible ways of going about this:
iterating through every element on the page, checking if it has text that is displayed and changing the text color. I guess this can be done by getting all elements using document.getElementsByTagName('html')[0].innerHTML and then calling elements[i].textContent to get the text but I do not know how to determine if the text is visible or not. This will return the text inside <script> elements and adding color attributes to those elements will break the page.
selecting the text on the page with something like window.getSelection().addRange(WholePage) but then I don't know of any way of changing the text color.
If you think of any other method please feel free to suggest it.
Try this (use jQuery).
$('p, li').each(function(){
var length = $(this).text().length;
var newStr = "";
for (var i = 0; i < length; i+=20) {
newStr += '<span style="color:red">' + $(this).text().substring(i, i + 10) + '</span>';
newStr += '<span style="color:blue">' + $(this).text().substring(i + 10, i + 20) + '</span>';
}
$(this).html(newStr);
});
In my word game there is a grid with 3 letter words.
The aim of the game is to spell the words by clicking on the corresponding letters on the side.
When an area in the grid is highlighted it indicates to the user the word to spell. The user clicks the letters on the side of the grid and they should move to the highlighted area.
I have recently changed "drop-box" to a div in the following piece of code and now the animation takes the letter to the top corner of the grid before taking it to the correct position.
var row = '<tr>';
var spaceAvailInRow = numLetters;
while (spaceAvailInRow) {
var word = getWordToFitIn(spaceAvailInRow, unusedShuffledWords);
guesses[word] = [];
spaceAvailInRow -= word.length;
for (var k = 0; k < word.length; ++k) {
row += '<td data-letter="' + word[k] + '" data-word="' + word + '"><div class="drop-box"></div></td>';
}
}
row += '</tr>';
tbl.append(row);
}
$(".container").append(tbl);
Can someone tell me why the animation has broke now I have changed this?
Fiddle: http://jsfiddle.net/7Y7A5/27/
The problem is that position() gets an element's position relative to its (offset) parent - in your case, each drop-box div is positioned at 0,0 releative to its containing td. What you need is the containing td's position(), not the drop-box's.
I've changed things around a little, and the fiddle can be seen here: http://jsfiddle.net/mHDkV/1/
I've changed the targetPos variable to refer to the position of the parent td, and applied the occupied class to that td as well. Take a look though the code in the jsFiddle - it should hopefully make sense.