Display first X elements obtained from a json if press a button - javascript

I'm noob in Javascript and I want to make a button for load images, my idea is.. Get the Json data from an url and save it in a js array.. if the user press the button, show the ten first images, and if press again show the next ten images, this to the end..
$(document).ready(function(){
var a = [""];
$.each(tumblr_api_read.posts, function(i, item) {
a[i] += '<li><img src="' + item['photo-url-500'] + '" alt="' + item.slug + '"/></li>';
});
$(".portfolio-margin").on("click", ".read-more", function(){
var i, b = "";
for (i = 1; i < 10; ++i) {
b += a[i];
}
$(".grid").append(b);
});
});
The code is not finished, but the problem.. I don't know how load the next images, and the var "b" returns "undefined" in the beginning of each li: undefined<li></li>undefined<li>..

The value of
a[i] +=
is considered as
a[i] = a[i] + new value
// ^ undefined initially
Initially, a[i] will always be undefined. So you are getting undefined.
Change that line to as I dont' see any reason to concatenate(+=). Iterator i will always occur once.
a[i] = '<li><img src="' + item['photo-url-500'] + '" alt="' + item.slug + '"/></li>';
// ^ Here

Related

document.write, Array.push and putting strings together

I want my code to be able to replace the current HTML page seen by the user via document.write(). And it does replace the HTML page, it just doesn't show the text that I want it to show. If I use my code to add an element via the addElement() function,
function addElement(a, b) {
var startTag, tagValue, endTag, finalTag;
// htmlify
if (b === undefined) {
startTag = "<p>";
endTag = "</p>";
} else {
startTag = "<" + b + ">";
endTag = "</" + b + ">";
}
finalTag = startTag + tagValue + endTag;
eio.push(finalTag);
};
it takes the parameters that the user has put in to create a valid tag, for example
addElement("This is a valid h1 tag.", "h1");
It then parses that into a HTML tag (variables filled out here),
var finalTag = "<" + "h1" + ">" + "This is a valid h1 tag." + "</" + "h1" + ">"
and pushes it into an array called eio (variables filled out again).
eio.push("<h1>This is a valid h1 tag.</h1>");
This array is not used until displayElements() is called, where I used a for loop to put all the different strings together. Here's how I did it:
function displayElements() {
finalString = "<!DOCTYPE html><html><head><title>Hello World!</title></head><body>";
for (i = 0; i === eio.length; i++) {
finalString += eio[i];
}
finalString += "</body></html>";
document.write(finalString);
};
Using our example again, finalString should look like this
finalString = "<!DOCTYPE html><html><head><title>Hello World!</title></head><body><h1>This is a valid h1 tag.</h1></body></html>"
when it we use it in the document.write() function. This should leave us with an HTML page where it says "This is a valid h1 tag." in big bold font, yet it only leaves us with a blank screen. One interesting thing however, is that the title does get updated when we call the function, but the page is still blank.
You can see the entire code here, and go to the example website here.
Two problems were already pointed out by sabithpocker and me. I will sum those up to make this answer.
Your addElement method takes an argument a and does nothing with it. Instead you are using a local variable tagValue. You could fix it by assigning the value of a to tagValue.
function addElement(a, b) {
var startTag, endTag, finalTag;
var tagValue = a;
// htmlify
if (b === undefined) {
startTag = "<p>";
endTag = "</p>";
} else {
startTag = "<" + b + ">";
endTag = "</" + b + ">";
}
finalTag = startTag + tagValue + endTag;
eio.push(finalTag);
};
The second problem is a typo in the for-loop of your displayElements method. It should be
for (i = 0; i < eio.length; i++) {
finalString += eio[i];
}

Creating and deleting divs using javascript

I have a few JavaScript functions designed to add and remove HTML divs to a larger div. The function init is the body's onload. New lines are added when an outside button calls NewLine(). Divs are removed when buttons inside said divs call DeleteLine(). There are a few problems with the code though: when I add a new line, the color values of all the other lines are cleared, and when deleting lines, the ids of the buttons, titles, and line boxes go out of sync. I've gone through it with the Chrome debugger a few times, but each time I fix something it seems to cause a new problem. I would greatly appreciate some input on what I'm doing wrong.
function init()
{
numOfLines = 0; //Keeps track of the number of lines the Artulator is displaying
}
function NewLine()
{
var LineBoxHolder = document.getElementById("LineBoxHolder");
numOfLines += 1;
LineBoxCode += "<div class = 'Line Box' id = 'LineBox" + numOfLines + "'>" //The code is only split onto multiple lines to look better
+ " <h6 id = 'Title " + numOfLines + "' class = 'Line Box Title'>Line " + numOfLines + "</h6>";
+ " <p>Color: <input type = 'color' value = '#000000'></p>"
+ " <input type = 'button' value = 'Delete Line' id = 'DeleteLine" + numOfLines + "' onclick = 'DeleteLine(" + numOfLines + ")'/>"
+ "</div>";
LineBoxHolder.innerHTML += LineBoxCode;
}
function DeleteLine(num)
{
deletedLineName = "LineBox" + num;
deletedLine = document.getElementById(deletedLineName);
deletedLine.parentNode.removeChild(deletedLine);
num++;
for ( ; num < numOfLines + 1 ; )
{
num++;
var newNum = num - 1;
var changedLineName = "LineBox" + num;
var changedHeaderName = "Title" + num;
var changedButtonName = "DeleteLine" + num;
var changedButtonOC = "DeleteLine(" + newNum + ")";
var changedLine = document.getElementById(changedLineName);
var changedHeader = document.getElementById(changedHeaderName);
var changedButton = document.getElementById(changedButtonName);
var changedLine.id = "LineBox" + newNum;
var changedHeader.innerHTML = "Line" + newNum;
var changedHeader.id = "Title" + newNum;
var changedButton.setAttribute("onclick",changedButtonOC);
var changedButton.id = "DeleteLine" + newNum;
}
num--;
numOfLines = num;
}
You are having a hard time debugging your code because of your approach. You are "marking" various elements with the IDs you construct, and using the IDs to find and address elements. That means that when things change, such as line being deleted, you have to go back and fix up the markings. Almost by definition, the complicated code you wrote to do something like that is going to have bugs. Even if you had great debugging skills, you'd spend some time working through those bugs.
Do not over-use IDs as a poor-man's way to identify DOM elements. Doing it that way requires constructing the ID when you create the element and constructing more IDs for the sub-elements. Then to find the element again, you have to construct another ID string and do getElementById. Instead, use JavaScript to manage the DOM. Instead of passing around IDs and parts of IDs like numbers, pass around the DOM elements themselves. In your case, you don't need IDs at all.
Let's start off with DeleteLine. Instead of passing it a number, pass it the element itself, which you can do my fixing the code inside your big DOM string to be as follows:
<input type='button' value='Delete Line' onclick="DeleteLine(this.parentNode)"/>
So we have no ID for the line element, no ID for the element, and no ID within the onclick handler. DeleteLine itself can now simply be
function DeleteLine(line) {
{
line.parentNode.removeChild(line);
renumberLines();
}
We'll show renumberLines later. There is no need to adjust IDs, rewrite existing elements, or anything else.
Since we no longer need the ID on each line or its sub-elements, the code to create each element becomes much simpler:
function NewLine()
{
var LineBoxHolder = document.getElementById("LineBoxHolder");
numOfLines += 1;
var LineBoxCode = "<div class='LineBox'>" +
+ " <h6 class='LineBoxTitle'>Line " + "numOfLines + "</h6>"
+ " <p>Color: <input type='color' value='#000000'></p>"
+ " <input type='button' value='Delete Line' onclick= 'DeleteLine(this.parentNode)'/>"
+ "</div>";
LineBoxHolder.innerHTML += LineBoxCode;
}
The only remaining work is to fix up the titles to show the correct numbers. You can do this by just looping through the lines, as in
function renumberLines() {
var LineBoxHolder = document.getElementById("LineBoxHolder");
var lines = LineBoxHolder.childElements;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
var h6 = line.querySelector('h6');
h6.textContent= "Line " + (i+1);
}
}
I voted to close because the question is too broad, but will answer anyway on a few points to... well, point in the right direction.
var changedButton.setAttribute("onclick",changedButtonOC); This is not a variable declaration. Omit the var.
for ( ; num < numOfLines + 1 ; ) { num++; ... The correct form here would be simply for (; num < numOfLines + 1; num++) { ....
Instead of incrementing (num++) then decrementing (num--) around the loop, why not just use the right math?
See:
for (; num < numOfLines; num++) {
...
}

Whats wrong with my javascript loop returning xml?

I have something wrong with my loop as it is returning all the name, link, image and content in one go instead of looping through evey event individually
var items=xml.getElementsByTagName('event').length;
//alert(items);
var name, link, image, content;
for (var i = 0; i < items; i++) {
//alert('in the loop');
name = $(xml).find('name').text();
link = $(xml).find('url').text();
image = $(xml).find('image').text();
content = $(xml).find('content').text();
$('#headername')
.append('<h3>' + name + '</h3><br /><img src="' + image + '" alt="' + name +'" width="100%"><br /><p>' + content
+ '</p><h4>Read more at: </h4><a rel="external" data-role="button" data-inline="true" data-icon="back" onclick="doOpen('' + link + '', '_blank');">' +name +'</a><br />' );
}
The problem is that $(xml).find('el') returns the first element found every time through the loop, whereas you want the nth one on the nth iteration.
Try this instead:
for (var i = 0; i < items; i++) {
name = $(xml).find('name').eq(i).text();
// ^^^^^^
// ...
}
Note also that it's not a very good idea to build HTML using +, since the data could contain HTML characters. They should be escaped with escape:
.append('<h3>' + escape(name) + /* ... */ );

Calling multiple functions to generate textboxes on same page

I am calling two separate functions to generate dynamic textboxes one of the function works fine whereas other doesn't work though the code for generating textboxes is same except the variables names and label names. Could anyone please let me know what I am doing wrong and how can i figure out this ?
this is the function which is not working.
var C = 3;
var matrixArray = ["question", "mrank"];
$("#addMatrix").click(function () {
for(var j = 0; j < matrixArray.length; j++){
createMatrixInput(MatrixArray[j]);
}
C++;
});
function createMatrixInput(l){
var tb_Div = $('#TextBoxes');
var mstr = '<div class="control-group">';
mstr += '<label class="control-label">' + l + " " + C + '</label>';
mstr += '<div class="controls">';
mstr += '<input type="text" id="' + l + '_' + C + '" name="'+ l +'_' + C + '" />';
mstr += '</div>';
mstr += '</div>';
tb_Div.append(mstr);
};
this is my jsfiddle with complete code.
http://jsfiddle.net/qqqyC/2/
There are 2 problems. The button id is addmatrix and the array is matrixArray, not MatrixArray. The method should look like:
$("#addmatrix").click(function () {
for(var j = 0; j < matrixArray.length; j++){
createMatrixInput(matrixArray[j]);
C++;
}
});
I've spotted a error in your JSFiddle see the id of your button "matrix button" it is addmatrix and you are binding the onClick event to addMatrix and javascript event binding via ID is case sensitive, so the event will not be bind.
Maybe this will solve your whole problem, because it was preventing to execute the click event.

Uncaught TypeError: Cannot read property 'name' of undefined

I have the following code for when 'choose file' is clicked:
$(':file').change(function () {
if(this.files.length == 1) {
$('#selected_files').html("<h4>Attaching " + this.files.length + " file</h4>");
} else {
$('#selected_files').html("<h4>Attaching " + this.files.length + " files</h4>");
}
$('#selected_files').append("<table class=\"altShaded\"><thead><tr><td></td><td>Filename</td><td>Size</td></tr></thead>");
for(x=0;x<=this.files.length;x++)
{
var file = this.files[x],
name = file.name,
size = file.size,
type = file.type;
$('#selected_files').append("<tr><td></td><td><b>" + name + "</b> ("+filesize(size)+") " + type + "<br>");
}
});
Fine, right? And all works well. That's great, except that when jQuery appends the table rows, it seems to like to start a new table, and the top <thead> isnt attached the to rows (in Chrome).
Okay I thought, we'll just build a string and put it all in at once.
Thus:
$(':file').change(function () {
if(this.files.length == 1) {
var displayFiles = "<h4>Attaching " + this.files.length + " file</h4>";
} else {
var displayFiles = "<h4>Attaching " + this.files.length + " files</h4>";
}
var displayFiles = displayFiles + "<table class=\"altShaded\"><thead><tr><td></td><td>Filename</td><td>Size</td></tr></thead>";
for(x=0;x<=this.files.length;x++)
{
var file = this.files[x],
name = file.name,
size = file.size,
type = file.type;
displayFiles = displayFiles + "<tr><td>" + type + "</td><td><b>" + name + "</b></td><td>"+filesize(size)+"</td></tr>";
}
$('#selected_files').html(displayFiles);
});
But now all of a sudden, I get the following error:
*Uncaught TypeError: Cannot read property 'name' of undefined *
Nothing has changed, except the code around it. It is pointing to:
name = file.name,
Can you tell me what the problem is here?
This type of error mean that your container variable fileis not defined.
You should use console.log at different places to see what is defined and what is not (your files array, etc.)
Also :
for(x=0;x<=this.files.length;x++)
Will be undefined for the last x value, because the last element of an array is at array.length - 1and not array.length, that gives you an undefined value at the end of your loop, probably the source of your error. In your case, x goes to the value this.files.length
Also, always use var, otherwise your xwill be a global variable, which can be another source of problems.
A correct loop should be :
for (var x = 0; x < this.files.length; x++)
I was having same error and it was happening because of a stupid mistake.
I removed on module from imports array and accidentally left comma on that line.....so there were two commas (,,) in imports: [] array....after removing one comma it solved the problem.
Here is the code with the problem,
for (var index = 0; index <= results.length; index++) {
//doSumthing
}
Working code ,
for (var index = 0; index < results.length; index++) {
//doSumthing
}
The problem was with the = operator in for loop statement. It was checking for the element that does not exist(last element+1) in the array.
Try removing = from your loop statement, like this.
for(var x = 0; x < this.files.length; x++){}
It might work!

Categories