Issue with where to put .innerHTML in my JS code - javascript

I am doing a simple assignment for one of my modules and I've come into this problem for the 3rd or 4th time. My problem is that as my code shows below when I put the .innerHTML attribute on the first line it does not work at all and there is no error in the console window. When I place the it after the info.innerHTML on the second line it does work. I have asked a tutor and he is stuck on why this is happening
var info = document.getElementById("pOutput").innerHTML;
info = "Sum: " + sum + "<br>Average: " + avg;
var info = document.getElementById("pOutput");
info.innerHTML = "Sum: " + sum + "<br>Average: " + avg;

The second variation that you've included is correct but needs getElementById() instead of GetElementById().
The top lines are incorrect because you are overriding the variable info with your string, not writing it into innerHTML.

When you set info to innerHTML, it's getting the value. You need to set info to document.GetElementById("pOutput"), and then set info.innerHTML:
var info = document.getElementById("pOutput");
info.innerHTML = "Sum: " + sum + "<br>Average: " + avg;

The reason why this is happening is because in the first bit of code, you capture the value of the innerHTML property of the element. For example, if your element has <div></div> inside it, the value of info will be "<div></div>". If you modified the innerHTML of the element after, the value of info would still be <div></div>. On the contrary, in the second bit of code, what you capture is a reference to the element. Therefore you can modify its properties and it will reflect on the element itself. The reason why this happens is explained here but to make it simple, some types (like strings and numbers) are copied as values and some other types (like Objects) are copied as references.

Related

Don't seem to get $().attr('src') to do its job

First post here, so please be gentle ;-)
I've been learning coding over the last couple of weeks by making a dummy page, and been implementing what i learn on it incrementaly as i progress, hence it's a mixed bag where the functionality/code is according to when i wrote it, based on pure html/CSS, inline javascript, external javascript, and finally jquery.
So i mostly wrapped it up and i'm now cleaning up the mess, and part of my mission is to cull functions and lines of codes, and in one of them i'm kind of stuck.
The before was 30 buttons calling to 30 different functions onclick like so:
function cell3() {
document.getElementById('base3').src='images/1/3/' + x + '.png';
document.getElementById('base3b').src='images/1/3/' + x + '.png';
document.getElementById('v2base3').src='images/2/3/' + x + '.png';
document.getElementById('v2base3b').src='images/2/3/' + x + '.png';
document.getElementById('cell3').style.backgroundColor= x ;
}
Where a global variable (x) defines the folder paths for images to replace the images within some divs when clicking the button (cell3). It also changes the bGroung color of it. Sorry if the naming is a bit confusing...
So i'm removing all 30 functions and the 30 onclick calls with this bit of jquery:
$('button').click(function(){
var eyeD = $(this).attr("id");
var newURLa = 'images/1/' + eyeD + '/' + x + '.png';
var newURLb = 'images/2/' + eyeD + '/' + x + '.png';
$('base' + eyeD).attr('src', newURLa);
$('base' + eyeD + 'b').attr('src', newURLa);
$('v2base' + eyeD).attr('src', newURLb);
$('v2base' + eyeD + 'b').attr('src', newURLb);
$(this).css( "background-color", x );
document.getElementsByid('check').innerhtml = eyeD;
});
For that to 'work' i changed the button's names from 'cell1', 'cell2, etc. to '1', '2', etc.
Now the thing is, when clicking on the buttons the var 'eyeD' takes the value from the button ok. ('1', '2', etc.). The elements ID's are formed correctly ('base1', 'base2'... 'base1b', base2b'...), and the URL's are formed correctly. (The last line in the code is a p element that displays values so i could try to troubleshoot it) The background color also changes as expected. But the images do not get replaced.
Tried adding commas to the resulting URL's in case it was a syntax issue, but nothing happens. i even went freestyle and tried it with the =url() on it, different commas in different places, etc. So basically scraping the barrel here. Also wrote a url without variables to see if that would work, but still nothing. Also getting no errors when looking at the console.
It's probably a basic 'DOH!' thing, but right now i have a mental block...
Also, is there a way to keep the original naming and just retrieve the numbering part of the ID's? Thought about using the [4] identifier to get the 5th digit, but that won't work when running double digit numbers. (10, 11, etc)
Thanks!
Your jQuery lines accessing the elements are missing the # sign.
Change these...
$('base' + eyeD).attr('src', newURLa);
To this...
$('#base' + eyeD).attr('src', newURLa);
Also, your last line where you use plain JS, can be done in jQuery as well with less code.
document.getElementsByid('check').innerhtml = eyeD;
To...
$("#check").html(eyeD);
However, you should always use distinct ID's for elements. If you need to use multiple elements at the same time, use a class instead.
$(".check").html(eyeD);
You're grabbing an element incorrectly.
Either Grab an element by it's class name like so:
$('.v2base' + eyeD + 'b').attr('src', newURLb);
Or by its ID:
$('#v2base' + eyeD + 'b').attr('src', newURLb);
Problem solved!! It was indeed calling the id with the hash, but also it has to be called with double quotation marks. Single inverted commas won't work.
So the working format is
$("#v2base" + eyeD + "b")
but it won't work like so
$('#v2base' + eyeD + 'b')
Thanks everyone, it's been emotional

Can read initial data attribute (data-*), but can't read updated data attribute

A page I am working on currently generates a div with an initial set of values, stored as JSON in a data-* attribute:
The JSON is:
{"name":"Qm9i","gen":"1","level":"4","topic":"","checked":"eyIxIjoiNCIsIjciOiI0IiwiOCI6IjQiLCI5IjoiNCJ9","pronoun":"2"}
In the element like this:
<div id="comment-1" class="container-element" data-all="{"name":"Qm9i","gen":"1","level":"4","topic":"","checked":"eyIxIjoiNCIsIjciOiI0IiwiOCI6IjQiLCI5IjoiNCJ9","pronoun":"2"}">
There are a number of these divs, with unique ID's, and the user can make a final edit to content within the div (and the changes are reflected in the data attribute) before final output.
When the user clicks EDIT, the following function is called:
// Get the id of the current comment block
var index = getIndex($(this).attr('id'));
var commentFrame = $('#comment-' + index);
var fr = commentFrame.attr('id');
console.log("Edit button for " + fr + " was clicked...");
var b64 = commentFrame.data('all').checked;
var lvl = commentFrame.data('all').level;
console.log("Retrieved from the bottom of the container...")
console.log("level: " + lvl + " , checked: " + b64 + " or " + atob(b64));
//rest of code here
(apologies for the abundance of log statements - I've ben trying to debug this for quite a while now)
When the EDIT button is first clicked, the code seems to execute correctly, and the data is retrieved, as evidenced in the console log...
Edit button for comment-1 was clicked...
Retrieved from the bottom of the container...
level: 4 , checked: eyIxIjoiNCIsIjciOiI0IiwiOCI6IjQiLCI5IjoiNCJ9 or {"1":"4","7":"4","8":"4","9":"4"}
... edits to the contents of the div are made, and the data attribute is updated with the new values in another function
var details = JSON.parse(parent.attr('data-all'));
details.checked = fdata.checked; //new value for 'checked'
details.level = avg.toFixed(2); //new value for 'level'
// update everything...
parent.attr('data-all', JSON.stringify(details));
...and this is immediately reflected in the data attribute for the div ('level' and 'checked' have both changed.
<div id="comment-1" class="container-element" data-all="{"name":"Qm9i","gen":"1","level":"3.25","topic":"","checked":"eyIxIjoiMSIsIjciOiIzIiwiOCI6IjQiLCI5IjoiNSJ9","pronoun":"2"}">
However...
The problem arises when you click edit on a previously edited div (for example if the user changes his mind a second time).
As one would expect, the exact same code block above is called, but instead of returning the updated 'level' and 'checked' values from the data attribute, it is instead returning the initial values for both 'level' and 'checked', which have been overritten in the tag by the earlier edit and shouldn't be accessible any more.
Edit button for comment-1 was clicked...
Retrieved from the bottom of the container...
level: 4 , checked: eyIxIjoiNCIsIjciOiI0IiwiOCI6IjQiLCI5IjoiNCJ9 or {"1":"4","7":"4","8":"4","9":"4"}
I've been racking my brain and staring at this for a while now and getting nowhere, so I was hoping that the good people here might be able to offer a suggestion as to where I might be going wrong.
data is not an accessor for data-* attributes. It accesses and manages jQuery's data cache for an element, which is initialized from data-* attributes but is otherwise completely disconnected from them. This is a point of confusion for a large number of people.
If you want to use the actual attribute, use attr("data-all") consistently in your code.
If you want to use jQuery's data cache for the element, use data("all") consistently in your code.
If you mix attr("data-all") and data("all") in your code, you will get inconsistent results.
Simpler example:
var d = $("#foo");
console.log("d.attr('data-all'): " + d.attr("data-all"));
console.log("d.data('all'): " + d.data("all"));
console.log("Updating the data cache doesn't update the attribute:");
d.data("all", "data updated");
console.log("d.attr('data-all'): " + d.attr("data-all"));
console.log("d.data('all'): " + d.data("all"));
console.log("Updating the attribute doesn't update the data cache:");
d.attr("data-all", "attr updated");
console.log("d.attr('data-all'): " + d.attr("data-all"));
console.log("d.data('all'): " + d.data("all"));
<div id="foo" data-all="initial"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Getting started with javascript, got a questions

I'm following w3school beginner tutorial for JS. There's something I don't understand from code below:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var cars = ["Saab","Volvo","BMW"];
var text = "";
for(var i = 0; i < cars.length; i++) {
text+=cars[i] + "<br>";
}
document.getElementById("demo").innerHTML = text;
</script>
</body>
</html>
Can someone explain me the logic of text+=cars[i]? I understand that += means increment, but I canĀ“t understand the logic behind adding the array element to variable text.
Thank you so much for your quick replies! I've got a follow up question: is there an alternative to display the same type of information with having to use the
var text = "";
and
text+=cars[i]
pieces of code? If so, how would the snippet of code look like and what should I insert into HTML if not
text
?
Thanks again!
a+=b is short for a=a+b. In your case you have text = text + cars[i] + "<br>".
text is a string, and you are using + to append a value from the array (that contains strings), and then append "<br>"
The value of text at the end of the loop is going to be
Saab<br>Volvo<br>BMW<br>
where br stands for line break. So that each of them gets printed on new line.
And the last line of code
document.getElementById("demo").innerHTML = text;
changes the value of html element which has id of demo to that of text.
text += cars[i] + '<br>';
Concatenates element i of the cars array to the text, separated by a <br> tag.
Consider it like this,
text+=cars[i] + "<br>";
is actually
text=text+cars[i]+"<br>";
so that rather than deleting the old value it will concatenate the new word with existing string.(String Concatenation).
PS:As a fellow beginner a small piece of advice rather than following W3 Schools please go to site like codecademy which helps you to learn along with practice and proper explanation.
Don't think of += as incrementing, that's ++.
a = a + b
a += b;
Those two statements are the same. The bottom one takes the variable on the left side (a) and appends the right side to it (b), and then assigns it all back to he left side (a). So it's just a shorthand.
So what you're doing in your code is appending the string from cars[i] to your variable text.
This would do the same thing:
text = text + cars[i] + "<br>";
Once the loop runs, you will have the following in text:
Saab<br>Volvo<br>BMW
In javascript + is used for string concatenation
The code
for(var i = 0; i < cars.length; i++) {
text+=cars[i] + "<br>";
}
is picking each element from the array and concatenating "" to it.
If you console log the text before setting the innerHTML, it looks something like this -
"Saab<br>Volvo<br>BMW<br>"
here they do it actually just to show theres no point of doing it this way they just wanna show to reach each individual inside an array and concatanate it into a string the very same thing you can do with Array.prototype.join() method dont think here that u must use as they show always concatanate into a string if you want you can simply use every single individual inside as u wish as well
+= is not increment. It's adding (in this case concatenation) and saving result in the same variable.
var a +=b;
Is the same to:
var = a + b;
In your case script concatenates all array elements into one string and adding <br> tags between them.

jquery replace the content of a div persistently

I am trying to replace the content of a div tag with a certain value every 50sec via polling and jQuery. And I would like to access the value of that updated div, so I can save a request to the backend.
My problem is that once the content has been replaced, the browser displays it correctly, however the HTML stays the same as the beginning. I'm afraid this is a rather basic question, but I'm really curious about this.
Here I prepared an example to illustrate the issue: http://jsfiddle.net/LJgN6/7/
And you can see it out ot JSfiddle's context to check the final HTML here: http://jsfiddle.net/LJgN6/7/show
I would like to achieve a way to have in the final HTML(i.e. right click, view page source):
num 1.1 replaced with num 1.2
num 2.1 replaced with num 2.2
...
The code that you see in the View Source window is the HTML that was sent to the browser before anything client side was allowed to modify the DOM. If you want to see the source as it is modified by your javascript, you need to inspect the DOM (IE F12, Firebug, etc.)
If you need to access this value that was inserted earlier, using javascript to access the contents of your element (ie. $('#number-2').text()) should return its contents as they are currently in the DOM.
EDIT: Corrected typo
It looks like you're already familiar with jQuery so I would go ahead and head over to the extremely helpful API and take a look at AJAX calls. There is plenty of documentation there that will help you.
http://api.jquery.com/jQuery.ajax/
Here's an idea. Take a look at my fiddle of your problem
$(document).ready(function(){
$('#number-1').html("num " + 1.1);
$('#number-2').html("num " + 2.2);
$('#number-3').html("num " + 3.3);
$('#number-4').html("num " + 4.4);
setInterval(function(){newInfo();}, 3000);
});
function newInfo(){
var firstDiv = $('#number-1');
var secDiv = $('#number-2');
var thdDiv = $('#number-3');
var frthDiv = $('#number-4');
var firstDivInfo = firstDiv.text().substr(4);
var secDivNewInfo = firstDiv.text().substr(4);
var thdDivNewInfo = secDiv.text().substr(4);
var frthDivNewInfo = thdDiv.text().substr(4);
var newNumber = (Math.random() + 1).toFixed(1);
secDiv.html("num " + secDivNewInfo);
thdDiv.html("num " + thdDivNewInfo);
frthDiv.html("num " + frthDivNewInfo);
firstDiv.html("num " + newNumber);
}

Problem disabling/enabling multiple form elements using javascript

I'm trying to disable/enable multiple form elements of an HTML page using javascript. I have a form with many fields, each row of the form has a checkbox to enable/disable the elements on the row.
The problem is, only the first two form elements get disabled (no matter the order). After that, the remaining javascript code in the function just won't be executed anymore.
Here's the code (it's part of a function called by the onChange attribute of every checkbox):
document.getElementsByName(prefix + "fase" + phaseNumber + "_" + objectNumber + "_quantity")[0].disabled = !theBox.checked;
document.getElementsByName(prefix + "fase" + phaseNumber + "_" + objectNumber + "_description")[0].disabled = !theBox.checked;
document.getElementsByName(prefix + "fase" + phaseNumber + "_" + objectNumber + "_price")[0].disabled = !theBox.checked;
document.getElementsByName(prefix + "fase" + phaseNumber + "_" + objectNumber + "_language")[0].disabled = !theBox.checked;
Each form element has a different (and unique) name, and the single lines of code work just fine... until you put them together.
For example: in the above code, "quantity" and "description" fields will get disabled/enabled, but "price" and "language" won't.
If i change the order of the lines, the first two get always executed, no matter what.
Then every line of code doesn't work; it's like it's commented. I even put some alerts to try debugging, but they just get ignored (no dialog shows up at all) if I insert them after the above code. The elements names are correct.
I'm sure I've made a mistake somewhere, but since the single lines of code are working, I don't know where to look... it's driving me nuts!
Please, I could really use some help.
I just made it work and, as I thought, it was a very bad mistake.
The problem was, not every form row in the HTML has all of those 4 fields. So, basically, I was trying to access a property of a null object.
I solved it by putting:
if( document.getElementById(id) != null )
before trying to manipulate the element.
Sometimes when you're in a hurry, you end up neglecting some very basic stuff...
Thank you for your time.

Categories

Resources