so I wrote a script to display 5 random arrays, but the page doesn't display anything.
here's the code:
<html>
<head>
<script>
function start(){
var arr(5),result;
result=document.getElementById("arraying");
result="<p>";
for(var i=0; i<5;i++){
arr[i]=Math.floor(Math.random()*10);
result+="arr["+i+"]= "+arr[i]+"</p><p>";
}
result+="</p>";
}
window.addEventListener("load",start,false);
</script>
</head>
<body>
<div id="arraying"></div>
</body>
</html>
I tried removing result=document.getElementById and write document.getElementById.innerHTML=result in the end of the function but didn't work. what's the error?
You cannot use the same variable for different purposes at the same time. First you assign a DOM element to result, and immediately on the next line you overwrite result with a string.
Build a string htmlStr inside your loop, and when that is done, assign this string to result.innerHTML property:
function start() {
let arr = [],
result, htmlStr = '';
result = document.getElementById("arraying");
htmlStr += "<p>";
for (let i = 0; i < 5; i++) {
arr[i] = Math.floor(Math.random() * 10);
htmlStr += "arr[" + i + "]= " + arr[i] + "</p><p>";
}
htmlStr += "</p>";
result.innerHTML = htmlStr;
}
window.addEventListener("load", start, false);
<div id="arraying"></div>
Looking at the code you seem to be missing some basic javascript concepts.
array size
This is probably your main issue:
var arr(5)
This does not make sense in javascript. Array length does not need to be predefined since all arrays are of dynamic length. Simply define an array like this:
var arr = []
Then later when you want to append new elements use push like this:
arr.push( Math.floor(Math.random()*10) )
adding html using innerHTML
There are different ways to dynamically inject html into your page. (It looks like) you tried to append the html as a string to the parent element. This is not possible.
You said you tried using innerHTML. That should work if used correctly.
A working implementation would work like this:
function start() {
var arr = []
var result = "<p>"
for(var i = 0; i < 5; i++) {
arr.push( Math.floor(Math.random()*10) ) // Btw this array isn't actually needed.
result += "arr[" + i + "] = " + arr[i] + "</p><p>"
}
document.getElementById("arraying").innerHTML = result
}
window.addEventListener("load", start, {passive: true});
adding html using createElement
A generally better way of dynamically adding html elements is via createElement.
This way you dont have to write html and are therefore less prone for making errors. It is also more performant and easier to integrate into javascript.
I think the best explaination is a commented implementation:
function start() {
var myDiv = document.getElementById("arraying") // get parent node
var arr = []
for(var i = 0; i < 5; i++) {
arr.push( Math.floor(Math.random()*10) )
var p = document.createElement("p") // create p element
p.innerText = "arr[" + i + "] = " + arr[i] // add text content to p element
myDiv.append(p) // append p element to parent element
}
}
window.addEventListener("load", start, {passive: true});
small tips
The let keyword works mostly the same as the var keyword, but is generally preferred because of some edge cases in which let is superior.
Fusing strings and variables using the plus operator is generally considered bad practice. A better way to do the string concatenation would have been
result += `arr[${i}] = ${arr[i]}</p><p>`
Related
In short: as a standalone function, my randomizer works. When put together with HTML and jQuery it doesn't work.
Details:
I am building a "randomizer" - an HTML input gets multiple words separated by a space from the user. Let's say it gets 5, 7, 10, 30 words, for example. Then, it returns randomly only three of these words to the user.
The idea is that the user input is a single string of many words. Then, the code (should) break down the string into an array of strings (using .split) and assign this new array to another variable. Then, this newly created array creates another new array which has only three randomly chosen words. Finally, this last array is what the user should see after clicking on the button.
I am coding that in Atom, saving the HTML/CSS/JS in local files on my laptop (Mac) and then run it on Chrome.
I am using jQuery 3.3.1. from a CDN.
Nature of the problem:
When HTML and JS run together the randomizer doesn't work - after few button clicks, it happens that I get two identical words which should be the case. It shouldn't be the case because I don't experience the same problem when I test only the JS code with a variable to which I assign few different words in one single string. My guess is that something happens when the jQuery gets the user input. However, I am totally not sure.
I am fighting this for two days now. I tried whatever I could think of.
Is the problem the way I link the JS functions and the HTML code via the jQuery event listener?
Or maybe my function itself is poorly written?
HTML / JS / jQuery code is below:
// Here begins the jQuery code
$(document).ready( () => {
let $button = $('.button');
let $userInput = $('#userInputField');
let $userOutput = $('.userOutput');
$button.on('click', () => {
var b = document.getElementById('userInputField').value;
var a = doEverything(b);
$userOutput.text(a);
});
}); // Here ends the jQuery code.
//------------------------------------------------------------------------------------------------------------------------
// Here begins the JavaScript code
var coolWords = [];
function doEverything(aString) {
var bString = aString.split(" ");
var finalResult = [];
for (let i = 0; i < bString.length; i++) {
coolWords.push(bString[i]);
};
newList = coolWords.slice();
for (let i = 0; i < 3; i++) {
var hey = newList.splice( Math.floor( Math.random() * newList.length ), 1) [0];
finalResult.push(" " + hey);
}; // [0] is used so finalResult receives only strings and not whole arrays with only one string in each array.
return ("Hey, the words are " + finalResult[0] + ", " + finalResult[1] + " and " + finalResult[2] + ".");
};
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<div id="button">
<input type="text" id="userInputField" value="">
<button class="button">Magic</button>
</div>
<div id="userOutput">
<p class="userOutput">test</p>
</div>
Here is your code updated to work as a Snippet,..
Unfortunately localStorage is blocked in Snippets,.. But the change to make it store in localStorage shouldn't be too hard.
update: Also if you look at the lines I've commented out with localStorage on, they should be what's needed to make your words persistent for your users if they come back.
// Here begins the jQuery code
$(document).ready( () => {
let $button = $('.button');
let $userInput = $('#userInputField');
let $userOutput = $('.userOutput');
$button.on('click', () => {
var b = document.getElementById('userInputField').value;
var a = doEverything(b);
$userOutput.text(a);
});
}); // Here ends the jQuery code.
//------------------------------------------------------------------------------------------------------------------------
// Here begins the JavaScript code
//var saved = localStorage.getItem("saved") || "[]";
var saved = "[]";
var coolWords = JSON.parse(saved);
function doEverything(aString) {
var bString = aString.split(" ");
var finalResult = [];
for (let i = 0; i < bString.length; i++) {
if (coolWords.indexOf(bString[i]) < 0) // added this bit..
coolWords.push(bString[i]);
};
newList = coolWords.slice();
for (let i = 0; i < 3; i++) {
var hey = newList.splice( Math.floor( Math.random() * newList.length ), 1) [0];
finalResult.push(" " + hey);
}; // [0] is used so finalResult receives only strings and not whole arrays with only one string in each array.
//localStorage.setItem("saved",JSON.stringify(coolWords));
return ("Hey, the words are " + finalResult[0] + ", " + finalResult[1] + " and " + finalResult[2] + ".");
};
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<div id="button">
<input type="text" id="userInputField" value="">
<button class="button">Magic</button>
</div>
<div id="userOutput">
<p class="userOutput">test</p>
</div>
I have an array I have generated and I want to display it in html as a vertical list, preferably as each individual element.
I have done this:
var a = _.intersection(viewedUserLikedUsersArray, loggedInLikedUsersArray);
for (var i=0; i < a.length; i++){
displayListOfMatches.innerHTML = a[i];
}
but obviously this way will replace the innerHTML with the last element in the array rather than stacking each one on top of each other
You'll probably get people saying to do this:
displayListOfMatches.innerHTML = "<p>" + a.join("</p><p>") + "</p>";
...which works but note that the content of the array entries will be parsed as HTML.
If that's not okay, you can either build an HTML string by replacing those characters via map:
displayListOfMatches.innerHTML = a.map(function(entry) {
return "<p>" + entry.replace(/&/g, "&").replace(/</g, "<") + "</p>";
}).join("");
...or build the elements as you go, perhaps with forEach:
displayListOfMatches.innerHTML = ""; // You can leave this out if it's empty
a.forEach(function(entry) {
var p = document.createElement("p");
p.appendChild(document.createTextNode(entry));
displayListOfMatches.appendChild(p);
});
Of course, in all cases, you can adjust it to use different elements/markup.
I have an array with a variable amount of records. And I want to print every record of the array in the same html page. I prefer it to display in a list.
I have the following code. However this does only print the last record of the array because it overwrites the previous record in my html ul-element.
for (var i = 0; i < feedbackGeenLid.length; i++)
{
document.getElementById("feedback").innerHTML= ("<li>"+feedbackGeenLid[i] + "</li>");
}
Does anyone have an idea on how to realize this?
Your code keeps replacing the innerHTML you need to add to it.
document.getElementById("feedback").innerHTML += ("<li>"+feedbackGeenLid[i] + "</li>");
^
|
Added + here
For better performance build one string and set it to innerHTML at the end of the loop.
var out = "";
for (var i = 0; i < feedbackGeenLid.length; i++)
{
out += "<li>"+feedbackGeenLid[i] + "</li>";
}
document.getElementById("feedback").innerHTML= out;
Another option, use appendChild()
you are rewriting the content in each loop. use a variable to concatenate the content and then put it in the element:
var html = '';
for (var i = 0; i < feedbackGeenLid.length; i++)
{
html += "<li>"+feedbackGeenLid[i] + "</li>";
}
document.getElementById("feedback").innerHTML= html;
I'm trying to load X amount of <li>'s into a <ul> via a for loop in a jquery function, and while I think I've got the syntax about right I'm not getting anything loading. (no problem with loading a single <li>, but none for multiples with the method I've tried)
Initially I attempted to pass a variable into the loop to determine the amount of increments: var peekListAmount = 5;
That didn't work so I went for a bog-standard loop incrementer. That doesn't work either so, after searching here and getting close, I have put together a fiddle to see if someone can point out what I'm doing wrong: http://jsfiddle.net/janowicz/hEjxP/8/
Ultimately I want to use Knockout.js to dynamically input a number to pass to the loop amount variable, but 1st things 1st.
Many thanks in advance.
When you do:
var peekListItem = $('<li>...</li>');
you're creating a single instance of an <li> node, encapsulated in a jQuery object.
Appending an already-present node to the DOM just removes it from its current place in the DOM tree, and moves it to the new place.
You need to create the node inside the loop, not outside, otherwise you're just re-appending the same node each time, not a copy of that node.
In fact, given you're not manipulating that node, you can just put the required HTML directly inside the .append() call without wrapping it in $(...) at all:
$(function() {
var peekList = $('<ul class="peekaboo-list">').appendTo('div.peekaboo-wrap');
function addLiAnchorNodes(nodeAmount) {
var html = '<li>' +
'<p class="peekaboo-text"></p></li>';
for (var i = 0; i < nodeAmount; ++i) {
peekList.append(html);
}
}
addLiAnchorNodes(5);
});
See http://jsfiddle.net/alnitak/8xvbY/
Here is you updated code
$(function(){
var peekList = $('<ul class="peekaboo-list"></ul>');
var peekListItem = '<li><p class="peekaboo-text"></p></li>';
//var peekListAmount = 5;
var tmp = '';
var addLiAnchorNodes = function (nodeAmount){
//var nodeAmount = peekListAmount;
for (var i = 0; i < 10; i++){
tmp += peekListItem;
}
peekList.append(tmp);
$('div.peekaboo-wrap').append(peekList); // This bit works fine
}
addLiAnchorNodes();
});
This should work. Instead of appending the list item in each loop, append the list only once at the end.
$(function(){
var peekList = $('<ul class="peekaboo-list"></ul>');
peekList.appendTo('div.peekaboo-wrap');
var addLiAnchorNodes = function (nodeAmount){
var list = "";
for (var i = 0; i < 10; i++){
list += '<li>Sample<p class="peekaboo-text"></p></li>';
}
peekList.append(list);
}
addLiAnchorNodes();
});
Here is the updated fiddle
Try this:
$(function(){
var peekList = $('<ul class="peekaboo-list"></ul>');
$(peekList).appendTo('div.peekaboo-wrap'); // This bit works fine
var addLiAnchorNodes = function (nodeAmount){
//var nodeAmount = peekListAmount;
for (var i = 0; i < 10; i++){
var peekListItem = $('<li><p class="peekaboo-text"></p></li>');
peekListItem.appendTo(peekList);
}
}
addLiAnchorNodes();
});
I have a problem to manipulate checkbox values. The ‘change’ event on checkboxes returns an object, in my case:
{"val1":"member","val2":"book","val3":"journal","val4":"new_member","val5":"cds"}
The above object needed to be transformed in order the search engine to consume it like:
{ member,book,journal,new_member,cds}
I have done that with the below code block:
var formcheckbox = this.getFormcheckbox();
formcheckbox.on('change', function(checkbox, value){
var arr=[];
for (var i in value) {
arr.push(value[i])
};
var wrd = new Array(arr);
var joinwrd = wrd.join(",");
var filter = '{' + joinwrd + '}';
//console.log(filter);
//Ext.Msg.alert('Output', '{' + joinwrd + '}');
});
The problem is that I want to the “change” event’s output (“var filter” that is producing the: { member,book,journal,new_member,cds}) to use it elsewhere. I tried to make the whole event a variable (var output = “the change event”) but it doesn’t work.
Maybe it is a silly question but I am a newbie and I need a little help.
Thank you in advance,
Tom
Just pass filter to the function that will use it. You'd have to call it from inside the change handler anyway if you wanted something to happen:
formcheckbox.on('change', function(cb, value){
//...
var filter = "{" + arr.join(",") + "}";
useFilter(filter);
});
function useFilter(filter){
// use the `filter` var here
}
You could make filter a global variable and use it where ever you need it.
// global variable for the search filter
var filter = null;
var formcheckbox = this.getFormcheckbox();
formcheckbox.on('change', function(checkbox, value){
var arr = [],
i,
max;
// the order of the keys isn't guaranteed to be the same in a for(... in ...) loop
// if the order matters (as it looks like) better get them one by one by there names
for (i = 0, max = 5; i <= max; i++) {
arr.push(value["val" + i]);
}
// save the value in a global variable
filter = "{" + arr.join(",") + "}";
console.log(filter);
});