Javascript won't search updated HTML - javascript

I've been doing tiny little projects to try to learn Javascript. When I was playing with Kahoot I noticed that even though it should be a different color ~25% of the time, it seems to be red the majority of the time.
I'm trying to make javascript code to put into the console that lets me automatically always choose red and then it records whether it was correct or incorrect.
To click red, I can do var red = document.getElementsByTagName("button")[0]; then red.click(), and to check if it's right or wrong I can do
if ((document.documentElement.innerText).indexOf('Incorrect') > -1) {
alert('Incorrect');
} else if ((document.documentElement.innerText).indexOf("Correct") > -1) {
alert('Correct');
}
This works... sometimes. I think I know the problem but I don't know how to fix it. The button red will disappear to display whether it was correct or incorrect, then it will pop back up.
Normally I can set the variable red, and it works, but the next time the button pops up and I set the variable again it says undefined. In order to fix this, I need to use inspect element to press "Edit HTML" then press Enter.
I think this helps because when it says undefined it's looking through an older version of the HTML, the one where the button is hidden, and when I edit the html it updates the html that the javascript is searching.
Edit: I'm bad at explaining, so here's a video on my problem: https://youtu.be/9WaIOPRny28

Related

Why is the alert, within an if statement, not closing when I click ok?

I'm programming a learner test, using checkboxes. Functional requirements, per the client, are that the learner must score 100% to pass. The learner gets 3 attempts to pass and then must start the course over at the beginning. After each of the first 2 wrong selections, the learner is sent back to the first question of the test; "#vidQ1".
So far, I have a 'wrong answer' alert that tells the user that they made a wrong selection and how many attempts they have left. This is done as soon as the user makes a wrong selection. It doesn't wait for a submit event. The alert is correctly displaying the message and the decremented 'attempt' variable value and is also logging the new attempt value to the console.
The problem is that the alert does not close when the 'OK' button is clicked. But the 'attempt' variable is decremented each time the 'OK' button is clicked and the new value is logged to the console. I can only close it by closing the entire window. So the function is stopping at the alert, and I don't know why.
var attempt = 3;
...
$('#ques01_b').click(function() {
if( $(this).is(':checked')) {
attempt --;
console.log(attempt);
alert("That is incorrect. You have this many attempts left: " +attempt);}
$("#vidQ01").focus();
});
JS Fiddle: https://jsfiddle.net/frankmix/h86n93bx/38/
Description:
The javascript in the Fiddle is a portion of the 'loadvideos.js' file I created and the checkbox icon manipulation used for custom check marks.
The JavaScript in the Fiddle is for the loading and playing back of ONE of total of 30 questions and accompanying video simulations, each with 3 checkboxed responses to choose from, into a single div (#vidContainer).
I recently added the var attempt = 3 (today).
When the correct checkbox is selected, the video simulation plays. When the video ends, the first question and possible answers fadeout and the next question and possible answers fades in, and when the learner selects the correct answer for the next question, the first video displays none, and the next video loads and plays, and so on, for 30 videos.
Each question is in its own fieldset, and each fieldset contains 3 checkbox containers div's, for the 3 choices, that allow for the custom checks (green checks for correct selections and red x's for wrong ones).
There is only the first question here. The correct response is A (the checkbox input id="ques01_a")
Below the function that fires when the correct selection is made is my initial attempt at handling a wrong choice' B, in this case (the checkbox input id="ques01_b")
Below that is the checkbox icon manipulation code for the first question
Everything works and is 508 compliant as well to this point.
I'm now trying to add functions for counting and handling wrong answers; starting at LINE 20 in the JS part of this fiddle. That is where I'm asking for your help at.
Sorry this is so wordy. I wanted to spare you all of that :)
Thanks again.

Keep cell color changed with checkbox on refresh

I have cells changing background color on checkbox check and I worked out how to keep the checkboxes checked on refresh (though looking back I don't think that works anymore), but I don't know how to keep the color change on refresh. I don't actually know Javascript at all and this is all from other questions but I want it to work. If I've done something completely wrong please correct me and don't assume I did it on purpose because I have absolutely no idea what I'm doing.
$(document).ready(function() {
$(".colourswitcher").click(function() {
if($(this).is(":checked")) {
$(this).closest("td").css("background","#ff3333");
}else {
$(this).closest("td").css("background","#202020");
}
});
});
$(function(){
var test = localStorage.input === 'true'? true: false;
$('input').prop('checked', test || false);
});
$('input').on('change', function() {
localStorage.input = $(this).is(':checked');
console.log($(this).is(':checked'));
});
Since you're new to javascript, I'm going to ask the dumb question: Have you included jQuery?
This code that you've pulled makes use of jQuery, a very useful library (not built-in to javascript) that has become so commonplace that people often don't even state its name when asking or answering a question involving it. But anytime you see that $ notation, you're probably dealing with jQuery.
You need to include the library file in your html file so it knows what those special symbols and syntax are:
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
If you're testing this stuff in Google Chrome, press F12 and view the developer console. You will see "undefined" errors in red when you are missing things like this.
Here's another answer assuming you have a better working knowledge than my first answer:
The first bit of your code runs when the html document has loaded and attaches an event listener to change the nearest cell background color accordingly when the checkbox is clicked. Note two things here though. 1) that behavior will be attached to all html elements with the class "colourswitcher", not just inputs. 2) that behavior assumes that what was clicked has a property "checked", which only a checkbox does.
The middle bit I presume is supposed to run once, when the page is first loaded, to get the saved state of the checkbox from localStorage. This bit could be moved into the document ready bit.
The third bit of your code attaches an event listener to every input element (not just checkboxes) such that every time one is clicked, a checked true/false state will be saved in localStorage.
localStorage is a convenient way to save information between browser refreshes. You can save anything you want, ie. localStorage.CandyCanes = 7 and that variable will be stored in the user's browser and can be recalled later. Note that your above code will only work as intended if there's a single checkbox, because you're using one slot, or one variable, in localStorage to save: localStorage.input.
That's all I'm going to elaborate on this for now. If this is more than you expected, then it's time to hunker down and learn, or get a professional involved.

This is hard to say concisely...but I'm having issues with my if/else javascript. "if" won't happen after "Else" does

I just started learning Javascript, so maybe this is doing exactly what it's supposed to be doing, but this is what I think is a problem.
I have a text box and submit button. I have a <p> of text that is hidden.
IF the user's text entered is what I want it to be, the <p> of text shows on submit.
ELSE (any other user's text), the text shows up, but
document.getElementById("id").innerHTML="Incorrect!";
document.getElementById("id").style.display="block;"
So, it works that if you enter the CORRECT word first, the <p> shows up.
If INCORRECT, it shows up, but with different text, ie, "incorrect!" So far, so good...
THE PROBLEM: After you get the text wrong, you can't try again, you have to refresh.
If you get it right, the right text shows, if you enter something else in after, the proper <p> follows, too, but if you try AFTER the wrong text is entered, it doesn't go back.
So once it's incorrect, you can't go back. So if someone got it wrong, and then put in the right word, they wouldn't be able to tell unless they refreshed and tried it again first.... Does this make sense? I hope I'm clear.
You haven't posted much code so I'll make some assumptions in this answer, which I hope are clear
Say you have your "text box" <input type="text" id="textbox"/> which I'll call box and your message area <p id="id">sometext</p> which I'll call msg
var box = document.getElementById('textbox'),
msg = document.getElementById('id');
Then in the code which handles the submit you have, say
if (box.value === 'foo') { // contains the right thing
// ...
} else { // contains the wrong thing
msg.innerHTML = 'Incorrect!';
msg.style.display = 'block';
}
Which you say works fine the first time around, but not the second, then you'll need to consider what has actually changed between these two invocations? Perhaps you should re-set the defaults before the if, for example I'm guessing your message starts hidden, so you could add the following before the if line to make sure you're starting from where you expect
msg.style.display = 'none';

Updating a text box with javascript

I am having some trouble with some javascript and how it can control the html "text box".
First, here's what I have;
javascript:
function UpdateOrder()
{
// enable/disable appropriate buttons
document.getElementById("reset").disabled=false;
document.getElementById("add").disabled=false;
document.getElementById("submit").disabled=false;
document.getElementById("edit").disabled=false;
document.getElementById("update").disabled=true;
// Show display box, 'DispCurOrder'
document.getElementById('all_labels').disabled=true;
}
function EditOrder()
{
// enable/disable appropriate buttons
document.getElementById("reset").disabled=true;
document.getElementById("add").disabled=true;
document.getElementById("submit").disabled=true;
document.getElementById("edit").disabled=true;
document.getElementById("update").disabled=false;
document.getElementById('all_labels').disabled=false;
}
The Idea is simple... I have some buttons and inputs to generate a 'line' of text that get's dumped to the disabled text box. If the operator notices that they made a type-o or want to change something, they click on 'edit order' and it disables all the regular buttons, and enables the text box and 'update' button. The 'update order' button reverses this.
Now, when I just use the add lines to the text box, all works well. You can see each line get appended to the text box (there's another java function that does a bunch of error checking and such, but the crux is that it takes the contents of the text box, parses it on the "\n" to an array, then appends the new line of text. It then takes the array and puts it all together as a new string and puts it back into the text box. Here is that portion without all the error checking stuff;
function AppendOrder()
{
// let's set up an error flag.
var AppendError="";
var str1=document.forms["MyForm"].DataEntry1.value;
var str2=document.forms["MyForm"].DataEntry2.value;
if( /* checking variable str1 for errors */)
{
AppendError="Error in str 1 here";
}
if( /* checking variable str1 for errors */)
{
AppendError=AppendError+"Error in str 2 here";
}
// Display the error message, if there are no errors, it will clear what was there.
$('#AppendStatus').html(AppendError);
if(AppendError=="")
{
// it's all good, update the display
// create line of text
curEntry=str1 + " -- " + str2;
// let's get the current order into a list
str=document.getElementById('all_data').innerHTML;
if(str1=="Empty")
{
// make curOrder = to 1 element array of curEntry
var curOrder=[curEntry];
}
else
{
// parse str1 into an array and parse it to curOrder.
// Then push curEntry on the end.
var curOrder=str1.split("\n");
curOrder.push(curEntry);
}
// now we should have an array called 'curOrder[]'. Let's show it
// on the web page.
$('#all_labels').html(curOrder);
}
}
Now, the problem that I'm having is that after I add a line or two (or more) to the display using the 'add' button and then go into the 'edit' mode (where the text box is enabled) and I make all my changes, the 'add' button doesn't work.
Oddly enough, when I press the 'reset' button (which is just a reset button) it then shows all the adds I did after the edit, and the edited stuff is gone.
Now... to the question... is there something I'm not understanding about the text box? Is there some trick I need to do to get it to work? Am I going about this all wrong? Should I be using a different tool for this other than the 'textbox'?
Any help is greatly appreciated!!
Greg
Found the typo in your jsFiddle.
The first thing that I did was to add:
alert('hi there');
to the very top of the script, inside the $(document).ready() wrapper. Note that on jsFiddle you cannot see the document.ready wrapper, it is invisibly included, so just put the alert at top of javascript block as I did (link to my new jsFiddle is at bottom of answer)
Next, I noticed that you are enabling/disabling several controls by referencing them individually by ID. You can reference several controls at one time if they share the same class, so I invented the class="orderentry" and added that attribute to each of those controls. This removed 8 lines of code, which made troubleshooting easier.
Then, I began deleting/undeleting. First, I deleted everything in the javascript panel except alert('hi there');, and ran the jsFiddle. The alert popped up. Great. So I used Ctrl+z to undelete everything. Next, I selected everything EXCEPT the next block of code, and deleted the selection. I ran the jsFiddle, and again the alert popped up.
I continued deleting/undeleting until I found out where the alert no longer worked -- and that revealed the offending code block. Just had to carefully study the syntax in that specific area and found the error:
$('#txtOrder').attr({'disabled':'disabled')}; <== ERROR: note final parentheses
instead of
$('#txtOrder').attr({'disabled':'disabled'}); <== CORRECT: note final parentheses
Hope this helped, good luck on the rest of your project.
Here is the corrected jsFiddle
You didn't share your HTML, so I made assumptions about what your markup looks like.
Working jsFiddle here
The above jsFiddle is a much simplified version of what you are creating. Obviously, it is very different from what you have done so that I could create it quickly.
Observe how I made certain things happen with jQuery; take what is useful and ignore the rest.
Specifically, you can see how I initially disabled the textarea control:
$('#txtArea').attr({'disabled':'disabled'});
Re-enabled the textarea control for editing, while also hiding the Edit button and displaying the Save button:
$('#txtArea').removeAttr('disabled');
$('#btnSave').show();
$(this).hide();
Importantly, this is how I ensure each addition adds to (rather than overwriting) existing content:
var ord = 'Requested By: ' + $('#txtReq').val() + '\r\n';
Very likely you already know many (most?) of the things I am pointing out, but I have no idea what you know so, again, keep the one or two things you find useful and ignore the rest. I only hope I've managed to hit on the bit that has you stumped at the moment.
I very rarely recommend W3Schools for anything, but look here for their excellent summary / reference of jQuery selectors, events, methods. (Keep hitting Next Chapter to cycle through all pages of this reference).

Problem getting selected text when using a sprited button and selection.createRange() in Internet Explorer

I'm working on implementing sprited buttons in Stackoverflow's beloved WMD markdown editor and I've run into an odd bug. On all versions of IE, the selected text is lost upon button clicks, so, say, highlighting a block of text and clicking the code button acts like you placed the cursor at the end of the selection and clicked the button.
e.g. highlighting this:
This
Is
Code
and clicking the code button give you:
This
Is
Code`enter code here`
What's really weird is that I left the original non-sprited button bar in and that works just fine. In fact ALL buttons and keyboard shortcuts code use the same doClick(button) function!
Old-style non-sprited buttons: OK
Keyboard shortcuts: OK
Sprited buttons in non-IE browsers: OK
Sprited buttons in IE: WTF
I've isolated the problem down to a call to selection.createRange() which finds nothing only when the sprited button is clicked. I've tried screwing around with focus()ing and making sure as little as possible happens before the doClick() but no joy. The keyboard shortcuts seem to work because the focus is never lost from the input textarea. Can anyone think of a hack that will let me somehow collect the selected text in IE?
The onclick handler looks like this:
button.onmouseout = function(){
this.style.backgroundPosition = this.XShift + " " + normalYShift;
};
button.onclick = function() {
if (this.onmouseout) {
this.onmouseout();
}
doClick(this);
}
I've tried moving the onmouseout call to after the doClick in case that was causing a loss of focus but that's not the problem.
EDIT:
The only thing that seems to be different is that, in the original button code, you are clicking on an image. In the sprited code, you are clicking on a list item <li> with a background image set. Perhaps it's trying to select the non-existent text in my list item?
/EDIT
Actual code is located in my wmd repository on git in the button-cleanup branch.
If you revert to the 0d6d1b32bb42a6bd1d4ac4e409a19fdfe8f1ffcc commit you can see both button bars. The top one is sprited and exhibits the weird behavior. The bottom one contains the remnants of the original button bar and works fine. The suspect code is in the setInputAreaSelectionStartEnd() function in the TextareaState object.
One last thing I should mention is that, for the time being, I'm trying to keep the control in pure Javascript so I'd like to avoid fixing this with an external library like jQuery if that's possible.
Thanks for your help!
I know what the answer to my own question is.
The sprited buttons are implemented using an HTML list and CSS, where all the list items have a background image. The background image is moved around using CSS to show different buttons and states (like mouseover highlights). Standard CSS button spriting stuff.
This works fine in IE with one exception: IE tries to select the empty list text when you click on the background image "button". The selection in the input textarea goes away and the current selection (which will be returned by document.selection.createRange()) is moved to the empty text in the list item.
The fix for this is simple - I created a variable to cache the selection and a flag. In IE I cache the selection and set the flag in a mousedown event handler. In the text processing, I check for the presence of the flag - if it's set I use the cached range instead of querying document.selection.createRange().
Here are some code snippets:
wmd.ieCachedRange = null;
wmd.ieRetardedClick = false;
if(global.isIE) {
button.onmousedown = function() {
wmd.ieRetardedClick = true;
wmd.ieCachedRange = document.selection.createRange();
};
}
var range;
if(wmd.ieRetardedClick && wmd.ieCachedRange) {
range = wmd.ieCachedRange;
wmd.ieRetardedClick = false;
}
else {
range = doc.selection.createRange();
}
The solution is only a few lines of code and avoids messing around with the DOM and potentially creating layout engine issues.
Thanks for your help, Cristoph. I came up with the answer while thinking and googling about your answer.
You have to blur() a button before IE can select anything else on a page.
Can you provide a minimal example (only containing relevant code) which reproduces the bug?

Categories