function create(param) {
var i, target = document.getElementById('results');
target.innerHTML = '';
for(i = 1; i <= param; i += 1) {
target.innerHTML +='<br>'
for(var j=1;j<=param;j+=1)
target.innerHTML += '<input type="text" id="a'+i+''+j+'" placeholder="a'+i+''+j+'">';
}
}
function saveData(param) {
var a = []
for(var i = 1;i<param;i+=1) {
a[i] = [];
for(var j = 1;j<param;j+=1)
a[i][j] = document.getElementById('"a'+i+''+j+'"').value;
}
var target = document.getElementById('ShowResults');
for(var i = 1;i<param;i+=1){
a[i] = [];
target.innerHTML +='<br>'
for(var j = 1;j<param;j+=1)
target.innerHTML +=a[i][j];
}
}
<button onclick="create(5)" style="widht:300px;height:30px;">Create table</button>
<div id="results"> </div>
<button id="takeResults" onclick="saveData(5)"style="widht:300px;height:30px;">Save data</button>
<div id="ShowResults"> </div>
Ok so i made a table whit js and gave every textbox id of "a'+i+''+j+'" but it seems that when i want to save the data it show's me the following error: Cannot read property 'value' of null
Can you guys tell me what i did wrong?
Here's the solution with some code improvements
As i said in the comment, you had a mistake in the code you getElementById('"a' + i + '' + j + '"') should be getElementById('a' + i + '' + j)
and there's a lot of unnecessary loops
function create(param) {
var target = document.getElementById('results');
target.innerHTML = '';
for (var i = 0; i < param; i++) {
target.innerHTML += '<br>'
for (var j = 0; j < param; j++)
target.innerHTML += '<input type="text" id="a' + i + '' + j + '" placeholder="a' + i + '' + j + '">';
}
}
function saveData(param) {
var target = document.getElementById('ShowResults');
target.innerHTML = '';
var a = []
for (var i = 0; i < param; i++) {
a[i] = [];
for (var j = 0; j < param; j++) {
target.innerHTML += document.getElementById('a' + i + '' + j).value;
}
target.innerHTML += '<br>'
}
}
<button onclick="create(5)" style="widht:300px;height:30px;">Create table</button>
<div id="results"> </div>
<button id="takeResults" onclick="saveData(5)" style="widht:300px;height:30px;">Save data</button>
<div id="ShowResults"> </div>
Change this...
a[i][j] = document.getElementById('"a'+i+''+j+'"').value;
to this...
a[i][j] = document.getElementById('a' + i + j).value;
You have two lots of quotes around the id when you create it, but you don't need to add them both when you're using getElementById. Just build the string and it will work.
There were some other issues with your code, mainly where you didn't have opening braces but you had closing braces. Copy/paste this and it should fix your issues...
function create(param) {
var i, target = document.getElementById('results');
target.innerHTML = '';
for(i = 1; i <= param; i += 1) {
target.innerHTML +='<br>'
for(var j=1;j<=param;j+=1) {
target.innerHTML += '<input type="text" id="a'+i+''+j+'" placeholder="a'+i+''+j+'">';
}
}
function saveData(param) {
var a = []
for(var i = 1;i<param;i+=1) {
a[i] = [];
for(var j = 1;j<param;j+=1) {
a[i][j] = document.getElementById('a' + i + j).value;
}
var target = document.getElementById('ShowResults');
for(var i = 1;i<param;i+=1) {
a[i] = [];
target.innerHTML +='<br>'
for(var j = 1;j<param;j+=1) {
target.innerHTML +=a[i][j];
}
}
}
}
Incidentally, using multiple layers of arrays can cause issues, mainly due to being unfriendly for the reader (or you in the future). I'd highly recommend using an array of objects instead, and naming things more appropriately than a, i & j.
Related
I would like to apply same piece of code to two objects in JavaScript.
When calling getElementsByClass ,there appears 2 objects in my website.So I would like to apply the same code for both of them.Currently I'm applying it to only one Object (text[0]) and I would like to implement it also to text[1] .
var text=document.getElementsByClassName("th");
var text =text[0];
var newDom = '';
var animationDelay = 6;
for(let i = 0; i < text.innerText.length; i++)
{
newDom += '<span class="char">' + (text.innerText[i] == ' ' ? ' ' : text.innerText[i])+ '</span>';
}
text.innerHTML = newDom;
var length = text.children.length;
for(let i = 0; i < length; i++)
{
text.children[i].style['animation-delay'] = animationDelay * i + 'ms';
}
}
I think you want to do the same thing with using item[0] and item[1] together.
You can create a function. Or call this function by iterating your items too.
var text=document.getElementsByClassName("th");
function myFunc(text) {
var newDom = '';
var animationDelay = 6;
for(let i = 0; i < text.innerText.length; i++)
{
newDom += '<span class="char">' + (text.innerText[i] == ' ' ? ' ' : text.innerText[i])+ '</span>';
}
text.innerHTML = newDom;
var length = text.children.length;
for(let i = 0; i < length; i++)
{
text.children[i].style['animation-delay'] = animationDelay * i + 'ms';
}
}
}
myFunc(text[0]); // call functions with your items.
myFunc(text[1]);
I recently started learning html/javascript and I want a temporary object to be filled with one of the objects from an array based on the current page number.
loadnextpage();
function loadnextpage() {
var curpage = allcontent[pagenumber];
pagenumber++;
changeDiv('title', '<span>' + curpage.pageNumber + '</span>' + curpage.title);
}
But when I try to run the code it keeps giving me an error message that curpage is undefined, after that it keeps running and thus the last line of code gives an error, when I ask for curpage.pageNumber. After that it stops running the code.
image clipping of my code with error message
What am I doing wrong?
edit:
here is the entire code:
var pagenumber = 0;
var receipt = [];
var price = 0;
var text = '{"page": [{"pageNumber": "1","title": "kies je formaat","optionName": "size","option": [{"text": "klein","value": "small","extraPrice": "100"},{"text": "middel","value": "medium","extraPrice": "200"},{"text": "groot","value": "large","extraPrice": "300"}]},{"pageNumber": "2","title": "kies je kleur","optionName": "colour","option": [{"text": "rood","value": "red","extraPrice": "10"},{"text": "groen","value": "green","extraPrice": "20"},{"text": "blauw","value": "blue","extraPrice": "30"}]}]}';
var allcontent = [];
allcontent = JSON.parse(text);
var imgpath = 'img/';
loadnextpage();
function loadnextpage(){
var curpage = allcontent[pagenumber];
pagenumber++;
changeDiv('title', '<span>' + curpage.pageNumber + '</span>' +
curpage.title);
var radiobuttons = '';
var radiobuttonid = [];
for(var i = 0; i < curpage.option.length; i++) {
var curradio = curpage.option[i];
radiobuttons += '<label><div class="selection-wrap">';
radiobuttons += curradio.text;
radiobuttons += ' <input type="radio" name="';
radiobuttons += curpage.optoinName;
radiobuttons += '" value="';
radiobuttons += curradio.value;
radiobuttons += '" id="';
radiobuttons += curpage.optoinName;
radiobuttons += '_';
radiobuttons += curradio.value;
radiobuttons += '"></div></label></br>';
radiobuttonid.push(curpage.optoinName + '_' + curradio.value)
}
changeDiv('choices', radiobuttons);
for(var i = 0; i < radiobuttonid.length; i++){
document.getElementById(radiobuttonid[i]).onclick = function(){
receipt[pagenumber-1] = curpage.option[i];
for(var i = 0; i < receipt.length; i++){
price += receipt[i].extraPrice;
}
changeImg('previewimg', imgpath + curpage.option[i].value +
'/preview.jpg');
changeDiv('previewprice', '<h1>€' + price + ',-</h1>');
};
}
};
function changeDiv(id, content) {
document.getElementById(id).innerHTML = content;
};
function changeImg(id, img){
document.getElementById(id).src = img;
};
This is a coin flipping randomizer. I need to print out 10 rows and 20 columns. This is where I am stuck. My code seems to randomize correctly every time I click my button, it displays 20 columns but I cannot seem to get it to print a second row. It may be something simple that I am just not catching. Anything will be appreciated.
Javascript Code
function toss()
{
var heads = "x ";
var tails = "o ";
var rows = 0;
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++)
{
var val = Math.floor( Math.random() * 2 );
if(val === 1)
{
arr[i] = " x";
}
else
{
arr[i] = " y";
}
document.getElementById("results").innerHTML = arr + "<br />";
}
delete arr;
rows++
}
}
HTML:
<html>
<head>
<title>Coin Flip</title>
<script src="Toss.js" type="text/Javascript"></script>
<style>
#results
{
display: block;
}
</style>
</head>
<body>
Push Button to Flip -> <input type="button" onclick="toss()" value=" Flip ">
<span id="results"></span>
</body>
</html>
The problem is you are replacing the entire results output each time you create a row with the new row. You need to append instead of replace. So change this:
document.getElementById("results").innerHTML = arr + "<br />";
To:
document.getElementById("results").innerHTML += arr + "<br />";
You also need to move the append of the result out of the inner for loop! If you leave the append within the for loop, you will see this behavior: http://jsfiddle.net/t1s93Lqz/3/
JSFiddle: http://jsfiddle.net/t1s93Lqz/2/
You are resetting the html inside the element each iteration through the loop
document.getElementById("results").innerHTML = arr + "<br />";
And while you could concatenate innerHTML each iteration to fix this:
document.getElementById("results").innerHTML += arr + "<br />";
This will cause the whole html for that element to be re-rendered. It would be better to either build the html string first and then set the element's innerHTML property or use DOM methods like appendChild/insertAdjacentHTML.
Build string first
var html = "";
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++) {
var val = Math.floor( Math.random() * 2 );
if(val === 1) {
arr[i] = " x";
} else {
arr[i] = " y";
}
}
//moved the concatenation out of the loop
//otherwise you will get a line each as the array is set
html += arr + "<br />";
rows++
}
document.getElementById("results").innerHTML = html;
Using insertAdjacentHTML
var element = document.getElementById("results");
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++) {
var val = Math.floor( Math.random() * 2 );
if(val === 1) {
arr[i] = " x";
} else {
arr[i] = " y";
}
}
element.insertAdjacentHTML('beforeend',arr+"<br />");
rows++
}
Demo
var rows = 0;
var element = document.getElementById("results");
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++) {
var val = Math.floor( Math.random() * 2 );
if(val === 1) {
arr[i] = " x";
} else {
arr[i] = " y";
}
}
element.insertAdjacentHTML('beforeend',arr+"<br />");
rows++
}
<div id="results"></div>
Also note your delete statement won't do anything as delete works on object properties, if you console.log( delete arr ) you will see it will print false
You are only printing the last row. Replace
document.getElementById("results").innerHTML = arr + "<br />";
with
document.getElementById("results").innerHTML += arr + "<br />";
http://jsfiddle.net/tovic/AbpRD/
Fiddle has JavaScript, HTML, CSS
When code is placed in web page and rendered it does not
behave as the fiddle does (i.e. no line numbers)
(function () {
var pre = document.getElementsByTagName('pre'),
pl = pre.length;
for (var i = 0; i < pl; i++) {
pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>';
var num = pre[i].innerHTML.split(/\n/).length;
for (var j = 0; j < num; j++) {
var line_num = pre[i].getElementsByTagName('span')[0];
line_num.innerHTML += '<span>' + (j + 1) + '</span>';
}
}
})();
Could anyone suggest performance improvements for the function I've written (below, javascript with bits of jquery)? Or point out any glaring, basic flaws? Essentially I have a javascript Google map and a set of list based results too, and the function is fired by a checkbox click, which looks at the selection of checkboxes (each identifying a 'filter') and whittles the array data down accordingly, altering the DOM and updating the Google map markers according to that. There's a 'fake' loader image in there too at the mo that's just on a delay so that it animates before the UI hangs!
function updateFilters(currentCheck) {
if (currentCheck == undefined || (currentCheck != undefined && currentCheck.disabled == false)) {
var delay = 0;
if(document.getElementById('loader').style.display == 'none') {
$('#loader').css('display', 'block');
delay = 750;
}
$('#loader').delay(delay).hide(0, function(){
if (markers.length > 0) {
clearMarkers();
}
var filters = document.aspnetForm.filters;
var markerDataArray = [];
var filterCount = 0;
var currentfilters = '';
var infoWindow = new google.maps.InfoWindow({});
for (i = 0; i < filters.length; i++) {
var currentFilter = filters[i];
if (currentFilter.checked == true) {
var filtername;
if (currentFilter.parentNode.getElementsByTagName('a')[0].textContent != undefined) {
filtername = currentFilter.parentNode.getElementsByTagName('a')[0].textContent;
} else {
filtername = currentFilter.parentNode.getElementsByTagName('a')[0].innerText;
}
currentfilters += '<li>' + $.trim(filtername) +
$.trim(document.getElementById('remhide').innerHTML).replace('#"','#" onclick="toggleCheck(\'' + currentFilter.id + '\');return false;"');
var nextFilterArray = [];
filterCount++;
for (k = 0; k < filterinfo.length; k++) {
var filtertype = filterinfo[k][0];
if (filterinfo[k][0] == currentFilter.id) {
var sitearray = filterinfo[k][1];
for (m = 0; m < sitearray.length; m++) {
var thissite = sitearray[m].split(',');
if (filterCount > 1) {
nextFilterArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
} else {
markerDataArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
}
}
}
}
if (filterCount > 1) {
var itemsToRemove = [];
for (j = 0; j < markerDataArray.length; j++) {
var exists = false;
for (k = 0; k < nextFilterArray.length; k++) {
if (markerDataArray[j] == nextFilterArray[k]) {
exists = true;
}
}
if (exists == false) {
itemsToRemove.push(j);
}
}
var itemsRemoved = 0;
for (j = 0; j < itemsToRemove.length; j++) {
markerDataArray.splice(itemsToRemove[j]-itemsRemoved,1);
itemsRemoved++;
}
}
}
}
if (currentfilters != '') {
document.getElementById('appliedfilters').innerHTML = currentfilters;
document.getElementById('currentfilters').style.display = 'block';
} else {
document.getElementById('currentfilters').style.display = 'none';
}
if (filterCount < 1) {
for (j = 0; j < filterinfo.length; j++) {
var filtertype = filterinfo[j][0];
if (filterinfo[j][0] == 'allvalidsites') {
var sitearray = filterinfo[j][1];
for (m = 0; m < sitearray.length; m++) {
var thissite = sitearray[m].split(',');
markerDataArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
}
}
}
}
var infoWindow = new google.maps.InfoWindow({});
var resultHTML = '<div id="page1" class="page"><ul>';
var count = 0;
var page = 1;
var paging = '<li class="selected">1</li>';
for (i = 0; i < markerDataArray.length; i++) {
var markerInfArray = markerDataArray[i].split('|');
var url = '';
var name = '';
var placename = '';
var region = '';
var summaryimage = 'images/controls/placeholder.gif';
var summary = '';
var flag = 'images/controls/placeholderf.gif';
for (j = 0; j < tsiteinfo.length; j++) {
var thissite = tsiteinfo[j].split('|');
if (thissite[0] == markerInfArray[2]) {
name = thissite[1];
placename = thissite[2];
region = thissite[3];
if (thissite[4] != '') {
summaryimage = thissite[4];
}
summary = thissite[5];
if (thissite[6] != '') {
flag = thissite[6];
}
}
}
for (k = 0; k < sitemapperinfo.length; k++) {
var thissite = sitemapperinfo[k].split('|');
if (thissite[0] == markerInfArray[2]) {
url = thissite[1];
}
}
var markerLatLng = new google.maps.LatLng(markerInfArray[1].toString(), markerInfArray[0].toString());
var infoWindowContent = '<div class="infowindow">' + markerInfArray[2] + ': ';
var siteurl = approot + '/sites/' + url;
infoWindowContent += '<strong>' + name + '</strong>';
infoWindowContent += '<br /><br/><em>' + placename + ', ' + region + '</em></div>';
marker = new google.maps.Marker({
position: markerLatLng,
title: $("<div/>").html(name).text(),
shadow: shadow,
icon: image
});
addInfo(infoWindow, marker, infoWindowContent);
markers.push(marker);
count++;
if ((count > 20) && ((count % 20) == 1)) { // 20 per page
page++;
resultHTML += '</ul></div><div id="page' + page + '" class="page"><ul>';
paging += '<li>' + page + '</li>';
}
resultHTML += '<li><div class="namehead"><h2>' + name + ' <span>' + placename + ', ' + region + '</span></h2></div>' +
'<div class="codehead"><h2><img alt="' + region + '" src="' + approot +
'/' + flag + '" /> ' + markerInfArray[2] + '</h2></div>' +
'<div class="resultcontent"><img alt="' + name + '" src="' + approot +
'/' + summaryimage +'" />' + '<p>' + summary + '</p>' + document.getElementById('buttonhide').innerHTML.replace('#',siteurl) + '</div></li>';
}
$('#filteredmap .paging').each(function(){
$(this).html(paging);
});
document.getElementById('resultslist').innerHTML = resultHTML + '</ul></div>';
document.getElementById('count').innerHTML = count + ' ';
document.getElementById('page1').style.display = 'block';
for (t = 0; t < markers.length; t++) {
markers[t].setMap(filteredMap);
}
});
}
}
function clearMarkers() {
for (i = 0; i < markers.length; i++) {
markers[i].setMap(null);
markers[i] = null;
}
markers.length = 0;
}
However, I'm suffering from performance issues (UI hanging) specifically in IE6 and 7 when the number of results is high, but not in any other modern browsers, i.e. FF, Chrome, Safari etc. It is much worse when the Google map markers are being created and added (if I remove this portion it is still slugglish, but not to the same degree). Can you suggest where I'm going wrong with this?
Thanks in advance :) Please be gentle if you can, I don't do much javascript work and I'm pretty new to it and jquery!
This looks like a lot of work to do at the client no matter what.
Why don't you do this at the server instead, constructing all the HTML there, and just refresh the relevant sections with the results of an ajax query?