So I'm making a simulation of the lottery. I generate 6 numbers between 0 and 40 and show them in the html id 'generated'. My problem is that if I click a second time on 'generate' (in my html page), the previous generated numbers are still a part of the array and still show up. Does anybody know how to clear the array when pushed on the button multiple times?
This is my Javascript code:
'use strict';
function generatenumbers(){
let number = [];
let i;
i=0;
for(i= 0; i <= 5; i++){
number[i] = Math.floor(Math.random()*40);
}
i = 0;
for(i=0; i<= number.length - 1; i++){
let node = document.createElement("LI");
let textnode = document.createTextNode(number[i]);
node.appendChild(textnode);
document.getElementById("generated").appendChild(node);
}
}
You are supposed to remove the previously appended children then add new ones.
var list = document.getElementById("generated");
list.removeChild(list.childNodes[0]); // for removing first child only
//for removing all children
var list = document.getElementById("genrated");
while (list.firstChild) {
list.removeChild(list.firstChild);
}
you don't want to clear the array...you want to clear the document.getElementById("generated") element before you call the loop, that way, there will always be 6 LI elements at the end of the function.
document.getElementById("generated").innerHTML = ""; // clear the element
for(i=0; i<= number.length - 1; i++){
let node = document.createElement("LI");
let textnode = document.createTextNode(number[i]);
node.appendChild(textnode);
document.getElementById("generated").appendChild(node);
}
Related
I have a script that creates a table with specifications given by the user.
The issue is that when the table is printed more than once, it prints below the other table. Turning a 10x10 table into a 10x20 table. (if that makes sense)
In previous assignments I used:
//Clean grid
while(grid.firstChild)
grid.removeChild(grid.firstChild);
to clear the grid, but this assignment is using jQuery and I am not sure how to do it. I've tried:
var divBlock = document.getElementById('my_table');
while (divBlock.firstChild) {
divBlock.removeChild(divBlock.firstChild);
and
$("#my_table").empty();
and
$("#my_table").remove();
and
$('#my_table').remove('table');
but neither seem to work, here is the full code:
// TODO: clear table
var $rows = $("#rows");
var $cols = $("#cols");
var $print_button = $("#print");
var $my_table = $("#my_table");
var $stats = $("#stats");
var arr = [];
var $table_obj = $('<table>'); //Create an element
var $row_obj;
var $col_obj;
var counter = 0;
$print_button.on('click', function() {print_pattern();});
function print_pattern()
{
// Clear table
// var divBlock = document.getElementById('my_table');
// while (divBlock.firstChild) {
// divBlock.removeChild(divBlock.firstChild);
// }
// $("#my_table").empty();
$('#my_table').remove('table');
// Get row and column values
var r = $rows.val(); //Get value of rows
element
var c = $cols.val(); //Get value of cols element
// Create 2-D Array
for (var i = 0; i < r; i++) {
arr[i] = [];
}
// Double for-loop to create table
for (var i = 0; i < r; i++) {
$row_obj = $('<tr>'); // Create row
for (var j = 0; j < c; j++) {
$col_obj = $('<td>'); // Create table cell
var n = Math.floor(Math.random()*10000)%100; //Math methods:
floor and random
$($col_obj).append(n); // Append random number to table cell
$($row_obj).append($col_obj); // Append column to row
$($table_obj).append($row_obj); // Append row to table object
// if random number > 90 -> make background color yellow
if (n > 90) {
$col_obj.css('background-color', 'yellow'); //Change css
counter++; // counter for stats
}
}
$($table_obj).append($row_obj); // Append row to table object
}
$($my_table).append($table_obj); // Append table to div container
// Stats calculation
$stats.html("<b>" + (counter/(r*c)*100).toFixed(2) + "%<b>");
//Change html content
counter = 0; // reset counter
// event function for removing a row when its clicked on
$('tr').on('click', function(){ $(this).fadeOut(500); });
}
So I've tried a number of things, I am not sure if I am just getting the syntax wrong or if I am using the wrong function to clear the div tag.
If anyone can point me in the right direction that would help a lot!
Thank you.
EDIT: I figured out the issue. My original while() block worked fine when I put all the variables inside the function.
First of all, you have to distinguish variables.
A. There is a variable that has to define 1 time, and any changes will
be stored on that.
B. And there is a variable that needs to be reset every function
called.
variable on condition b you need put inside your function so it won't keep last value and make it has double value (last value + new value)
in this case i could say this variable is on condition b:
$table_obj, $row_obj, $col_obj, arr, ...
I am practicing my javascript. I have created a link to show hide paragraphs. The code currently uses 2 'for' loops. Should I somehow be creating a function for the 'for' loop and then re-use the function?
var paragraphs = document.getElementsByTagName('p'),
firstParagraph = paragraphs[0],
link = document.createElement('a');
link.innerHTML = 'Show more';
link.setAttribute('class', 'link');
link.setAttribute('href', '#');
firstParagraph.appendChild(link);
for (var i = 1; i <= paragraphs.length - 1; i++) {
paragraphs[i].classList.add('hide')
}
function toggleHide(e) {
e.preventDefault;
var paragraphs = document.getElementsByTagName('p');
for (i = 1; i <= paragraphs.length - 1; i++) {
paragraphs[i].classList.toggle('hide');
}
}
link.addEventListener('click', toggleHide)
Since toggle('hide') will also do the same thing of add('hide') when initializing the paragraph list, it is good to pull up the duplicate code to a single function.
For example:
var paragraphs = document.getElementsByTagName('p'),
firstParagraph = paragraphs[0],
link = document.createElement('a');
link.innerHTML = 'Show more';
link.setAttribute('class' , 'link');
link.setAttribute('href' , '#');
firstParagraph.appendChild(link);
toggleHideAll();
function toggleHide( e ){
e.preventDefault;
var paragraphs = document.getElementsByTagName('p');
toggleHideAll();
}
function toggleHideAll(){
for( i = 1 ; i <= paragraphs.length-1 ; i++){
paragraphs[i].classList.toggle('hide');
}
}
link.addEventListener( 'click' , toggleHide)
Yes, a single loop to achieve both ends would be good, as #Solmon says:
function toggleHideAll(){
for (var i = 1; i <= paragraphs.length-1; i++) {
paragraphs[i].classList.toggle('hide');
}
}
There is a more idiomatic way to express this loop, however, and I would advise you to use it, because the original form is confusing to developers who are accustomed to the standard form:
function toggleHideAll() {
for (var i = 0; i < paragraphs.length; i++) {
paragraphs[i].classList.toggle('hide');
}
}
That is, loop starting at zero, while the loop variable is less than length (not less than or equal to length minus one. And in this case, the loop does not do exactly the same as your original, because the original actually skips your first paragraph. If that's intentional, rather than tweaking the loop parameters, I would recommend toggling all of the paragraphs and then handling the special case with a line of code outside the loop:
function toggleHideAll() {
for (var i = 0; i < paragraphs.length; i++) {
paragraphs[i].classList.toggle('hide');
}
paragraphs[0].classList.remove('hide');
}
Also, it's really nice when you can avoid explicit loops in your code altogether:
function toggleHideAll() {
paragraphs.forEach(p => p.classList.toggle('hide'));
paragraphs[0].classList.remove('hide');
}
I have an JS Array that is supposed to show only one element. It does, however its index is 1 rather than 0 and the count is 2. Also the array does not show a 0 index.
My code:
var _UnitOfMeasureRelatedUnitData = [];
var rows = $('#jqxUOMRelatedUnitsDropdownGrid').jqxGrid('getrows');
var RecordCount = 0;
if (rows.length !== 1 && rows[0]["UOMRelatedUnit_Name"] !== ""){
for(var i = 0; i < rows.length; i++){
var row = rows[i];
var _row = {};
if(row.UOMRelatedUnit_AddItem !== F) {
RecordCount += 1;
_row["Name"] = $("#txtUnitOfMeasureSetName").val();
_row["Active"] = T;
_row["UnitOfMeasureTypeID"] = $("input[type='radio'][id='rblUnitOfMeasureType']:checked").val();
_row["BaseUnitID"] = $("input[type='radio'][id='rblUnitOfMeasureBaseUnit']:checked").val();
_row["RelatedUnitDisplayOrder"] = RecordCount;
_row["RelatedUnitName"] = row.UOMRelatedUnit_Name;
_row["RelatedUnitAbbreviation"] = row.UOMRelatedUnit_Abbreviation;
_row["RelatedUnitConversionRatio"] = row.UOMRelatedUnit_ConversionOfBaseUnits;
_row["UnitOfMeasureSetID"] = UnitOfMeasureSetID;
_UnitOfMeasureRelatedUnitData[i] = _row;
}
}
....
}
In my JQx Grid, I have at least four choices. For this issue, Ive only selected the 2 choice in the Grid and its AddItem value is True, everything else is False.
What do I need to change in my logic as I can not see it at this point?
EDIT 1
I overlooked the placement of RecordCount += 1;, I will try moving it to the end of the assignments and see what happens.
EDIT 2
The placement made no difference.
Maintain another variable for indexing your data like this
var index=0; // place this outside of for loop
_UnitOfMeasureRelatedUnitData[index++] = _row;
you don't need RecordCount += 1; .
you can get the rowscount by using _UnitOfMeasureRelatedUnitData.length
here is the deal, i have the following jquery code that should add the array values to specific #id, buf it does not replace the code, only add more, and i need a little help to make it replace the html on othe link click.
Code:
function changeClass(curClass){
switch(curClass){
case "Schoolgirl":
case "Fighter":
var charSkillsNames = ["text1","text2","text4","text5"];
//loop show array values
listSkillsNames(charSkillsNames);
break;
}
}
function listSkillsNames(arr){
var length = arr.length,
element = null;
$("#skills").html(function(){
for (var i = 0; i < length; i++) {
element = arr[i];
$(this).append("<li>"+element+"</li>");
}
});
}
this works well but i need it to replace the html inside the "#skills" id when i click on the link that makes it work
PS: problem is really here
The issue is that you don't empty the HTML of #skills element. Use $("#skills").html("") to empty it.
function listSkillsNames(arr){
var length = arr.length,
element = null;
var $skills = $("#skills");
$skills.html(""); // empty the HTML
for (var i = 0; i < length; i++) {
element = arr[i];
$skills.append("<li>"+element+"</li>"); // append new items
}
}
The problem is because you are keep appending new items to the element always without removing the existing items.
Just empty the skill element, also there is no need to use the .html(function(){}) here
function listSkillsNames(arr) {
var length = arr.length,
element = null;
var $skill = $("#skills").empty();
for (var i = 0; i < length; i++) {
element = arr[i];
$skill.append("<li>" + element + "</li>");
}
}
As you can see I am still a novice in javascript
Why is it so that you can append a Textnode only once? When you add it again somewhere else the first one disappears
I do not need a solution to a problem I was just curious what is causing this behavior.
Example where the textnode is only added to the last element of an array:
function hideAdd(){
var hide = document.createTextNode('Afbeelding verbergen');
var afb = collectionToArray(document.getElementsByTagName('img'));
afb.pop();
var divs = [];
for (i=0; i < afb.length; i++){
divs.push(afb[i].parentNode);
}
console.log(divs);
for ( i = 0; i < divs.length;i++){
divs[i].appendChild(hide);
}
}
This is where you use an unique textnode so it works:
function hideAdd(){
var hide = []
var afb = collectionToArray(document.getElementsByTagName('img'));
afb.pop();
var divs = [];
for (i=0; i < afb.length; i++){
divs.push(afb[i].parentNode);
hide[i] = document.createTextNode('Afbeelding verbergen');
}
console.log(divs);
for ( i = 0; i < divs.length;i++){
divs[i].appendChild(hide[i]);
}
}
Short answer is the DOM is a tree, not a network. Each node can have only one parent. If you could add a node in more than one location, it would have more than one parent.