Javascript String Appending

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

30 Replies - 4528 Views - Last Post: 28 November 2010 - 06:47 PM

#1 Ntwiles  Icon User is offline

  • D.I.C Addict

Reputation: 148
  • View blog
  • Posts: 830
  • Joined: 26-May 10

Javascript String Appending

Posted 26 November 2010 - 01:53 AM

Hey guys, I'm having some trouble with Javascript strings. The following works great:
   
for (i=0;i<::PostCount::;i++)
{
   postcell.innerHTML+="<table class='table_post'>"+"<tr><td>test</td></tr>"+"<tr><td class='td_post'>"+post[i]+"</td></tr>"+"</table>";
}


While the following doesn't:
  
for (i=0;i<::PostCount::;i++)
{
   postcell.innerHTML+="<table class='table_post'>";
   postcell.innerHTML+="<tr><td>test</td></tr>";
   postcell.innerHTML+="<tr><td class='td_post'>"+post[i]+"</td></tr>";
   postcell.innerHTML+="</table>";
}


I'd like to avoid having all the string modification done in one line for readability purposes. I don't really understand what the problem is.

In case this is related to the problem, this is from a .js file that is being read with PHP, modified (to replace ::PostCount:: with a number), then spat back out with echo. I don't believe this is involved in the issue though, as the viewed source on the end product looks just as it should. Can someone tell me what my problem is? Thanks (:

Is This A Good Question/Topic? 0
  • +

Replies To: Javascript String Appending

#2 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3572
  • View blog
  • Posts: 10,414
  • Joined: 08-June 10

Re: Javascript String Appending

Posted 26 November 2010 - 02:26 AM

.innerHTML and tables donít work well together (rule of thumb, see MSDN).

if you assign the <table> line (I assume that) the element becomes a table element and further use of .innerHTML gets problematic.
Was This Post Helpful? 1
  • +
  • -

#3 Ntwiles  Icon User is offline

  • D.I.C Addict

Reputation: 148
  • View blog
  • Posts: 830
  • Joined: 26-May 10

Re: Javascript String Appending

Posted 26 November 2010 - 02:36 AM

I see. Is there some way around that problem? I have to have a table created for each post, and I would really prefer to use Javascript instead of PHP so that I can implement AJAX to modify the posts without reloading the page.
Was This Post Helpful? 0
  • +
  • -

#4 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3572
  • View blog
  • Posts: 10,414
  • Joined: 08-June 10

Re: Javascript String Appending

Posted 26 November 2010 - 02:50 AM

afaik, you can only use DOM (Element.appendChild()) or the complete string (as in code block 1)

on the other hand side, PHP seems better suited to print long tables than Javascript (if you ask me, esp. if you have output from a database*)

PS. better use a <tbody> for each entry, than a <table> (makes more sense)


* - you can do that with a simple foreach() loop: foreach ($ps as $entry) { echo $entry; }

This post has been edited by Dormilich: 26 November 2010 - 02:52 AM

Was This Post Helpful? 1
  • +
  • -

#5 Ntwiles  Icon User is offline

  • D.I.C Addict

Reputation: 148
  • View blog
  • Posts: 830
  • Joined: 26-May 10

Re: Javascript String Appending

Posted 26 November 2010 - 03:39 AM

Thank you very much for the information. This seemed to do the trick:

   
var newnode = document.createElement("tbody");
postcell.appendChild(newnode);
for (i=0;i<::PostCount::;i++)
{      
   newnode.innerHTML+="<tbody class='table_post'>";
   newnode.innerHTML+="<tr><td>"+title[i]+"</td></tr>";
   newnode.innerHTML+="<tr><td class='td_post'>"+post[i]+"</td></tr>";
   newnode.innerHTML+="</tbody><br>";
}


Yeah I agree PHP is much easier, that's how I originally showed the posts. But I want the user to be able to delete a post and have it be removed from the feed, all without reloading the page. I can only do that with AJAX as far as I know.

This post has been edited by Ntwiles: 26 November 2010 - 03:42 AM

Was This Post Helpful? 0
  • +
  • -

#6 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3572
  • View blog
  • Posts: 10,414
  • Joined: 08-June 10

Re: Javascript String Appending

Posted 26 November 2010 - 03:46 AM

- shouldnít line 1 be <table>?
- <br> is not allowed after <tbody> (tbody is already a block element)
- for performance reasons, put line 2 after the for loop.
Was This Post Helpful? 0
  • +
  • -

#7 Ntwiles  Icon User is offline

  • D.I.C Addict

Reputation: 148
  • View blog
  • Posts: 830
  • Joined: 26-May 10

Re: Javascript String Appending

Posted 26 November 2010 - 04:52 AM

In the end I completely removed the tbody and just went back to nested tables. I needed css attributes that tbody didn't seem to have. I'm not sure what you mean by line 1 needing to be <table>?

I seem to be still having some trouble with these. Here's what I'm using now:

   var newnode = document.createElement("table");
   for (i=0;i<::PostCount::;i++)
   {      
      newnode.innerHTML+="<table onmouseover='selectpost("+postid[i]+");' onmouseout='deselectpost("+postid[i]+");' class='table_post'>";
      newnode.innerHTML+="<tr><td>"+title[i];
      newnode.innerHTML+="<span onclick='deletepost("+postid[i]+");' class='deletepostoff' id='delete_"+postid[i]+"'></span></td></tr>";
      newnode.innerHTML+="<tr><td class='td_post' id='post_"+postid[i]+"'>"+post[i]+"</td></tr>";
      newnode.innerHTML+="</table><br>";
   }
   postcell.appendChild(newnode);



The onclick event seems to work right, but the onmouseover/onmouseout events don't seem to be registering at all. Is this part of the same problem? Everything worked fine when I used PHP to display this information, so I assume it has to be.

This post has been edited by Ntwiles: 26 November 2010 - 04:53 AM

Was This Post Helpful? 0
  • +
  • -

#8 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3572
  • View blog
  • Posts: 10,414
  • Joined: 08-June 10

Re: Javascript String Appending

Posted 26 November 2010 - 04:58 AM

View PostNtwiles, on 26 November 2010 - 11:52 AM, said:

I'm not sure what you mean by line 1 needing to be <table>?

you are not allowed to put a <tbody> inside anything other than <table>.

View PostNtwiles, on 26 November 2010 - 11:52 AM, said:

In the end I completely removed the tbody and just went back to nested tables. I needed css attributes that tbody didn't seem to have.

that’s just a matter of fixing the CSS.


for the mouseover/mouseout issue I’d have to look at an example page. depending on what selectpost() does, you might even get away with CSS.

I strongly suspect that you can solve quite some issues by using external Javascript …

This post has been edited by Dormilich: 26 November 2010 - 05:02 AM

Was This Post Helpful? 0
  • +
  • -

#9 Ntwiles  Icon User is offline

  • D.I.C Addict

Reputation: 148
  • View blog
  • Posts: 830
  • Joined: 26-May 10

Re: Javascript String Appending

Posted 26 November 2010 - 05:09 AM

Oh I see what you mean. That code is from inside a function. The table it's inside is elsewhere in the document.

What do you mean by external javascript? This is all part of a .js file. All the html is in a separate .html file and all the PHP is in its own file as well.

I'm developing the site offline or I would just link you to it. Here's the .js file in it's entirety though:

<script>
function selectpost(id)
{
   var deleteid = "delete_"+id;
   document.getElementById(deleteid).className="deleteposton";
}

function deselectpost(id)
{
   var deleteid = "delete_"+id;
   document.getElementById(deleteid).className="deletepostoff";
}
   
function deletepost(id)
{
   confirm("Are you sure you want to delete this post?");
}

function displayposts()
{
   var title = new Array();
   var post = new Array();
   var postid = new Array();
   var postelem = document.getElementById('postcell');

   ::PostVars::
   postcell.innerHTML="";
   var newnode = document.createElement("table");
   for (i=0;i<::PostCount::;i++)
   {      
      newnode.innerHTML+="<table onmouseover='selectpost("+postid[i]+");' onmouseout='deselectpost("+postid[i]+");' class='table_post'>";
      newnode.innerHTML+="<tr><td>"+title[i];+"</td><td>";
      newnode.innerHTML+="<span onclick='deletepost("+postid[i]+");' class='deletepostoff' id=delete_"+postid[i]+">d</span></td></tr>";
      newnode.innerHTML+="<tr><td class='td_post' id=post_"+postid[i]+">"+post[i]+"</td></tr>";
      newnode.innerHTML+="</table><br>";
   }
   postcell.appendChild(newnode);
}
</script>


And here's the html file for what it's worth:

<html>
<head>
::CSS::
::Java::
</head>
<body onload="displayposts();">
<table>
<tr>
<td width=200>
::ProfilePic::
<br>
::DisplayName::
<br>
</td>
<td id='postcell'>
</td>
</tr>
</table>
<span id='test'></span>
</body>
</html>

This post has been edited by Ntwiles: 26 November 2010 - 05:11 AM

Was This Post Helpful? 0
  • +
  • -

#10 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3572
  • View blog
  • Posts: 10,414
  • Joined: 08-June 10

Re: Javascript String Appending

Posted 26 November 2010 - 05:17 AM

ok, I was a bit unclear. I meant, many problems can be avoided by not using inline-Javascript (where you use event attributes).

OK, some comments to your functions:
- why passing a parameter to deletepost()? it is not used.
- selectpost()/deselectpost(), I assume that triggers some kind of colour change. you can do that more efficiently with CSS:
table span {
	color: black;
}
table:hover span {
	color: red;
}

Was This Post Helpful? 0
  • +
  • -

#11 Ntwiles  Icon User is offline

  • D.I.C Addict

Reputation: 148
  • View blog
  • Posts: 830
  • Joined: 26-May 10

Re: Javascript String Appending

Posted 26 November 2010 - 05:44 AM

Ohh I see what you mean. Sorry for the dual question by the way this is one I should have made a second topic for. I've never used external event handling for Javascript. I've started with this:

function rollover()
{
   document.getElementsByClass('table_post').onmouseover= selectpost(6);
}


(6 is just a number that I happen to know is the id for one of my posts, just to keep it simple for now).

Do I have to call this on my own, or will it automatically call selectpost(6) when the a table with the class 'table_post' is moused over? It doesn't seem to be doing anything now, but I don't know how to call a function once every second.

To respond to your comments, the deletepost function is just unfinished. The parameter will be the id of the post to be deleted. As for the selectpost/deselectpost, really all they're changing for now is that when the user mouses over a post, a gray X should appear on the top right. When the user mouses over that X, it should turn black, and should be clickable to delete the post. I had it working with the PHP version using a combination of Javascript and css.

This post has been edited by Ntwiles: 26 November 2010 - 05:46 AM

Was This Post Helpful? 0
  • +
  • -

#12 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3572
  • View blog
  • Posts: 10,414
  • Joined: 08-June 10

Re: Javascript String Appending

Posted 26 November 2010 - 06:11 AM

View PostNtwiles, on 26 November 2010 - 12:44 PM, said:

function rollover()
{
   document.getElementsByClass('table_post').onmouseover= selectpost(6);
}

won’t work.
- you must pass a function to the events, not a result of a function (unless that itself is a function)
- a HTMLCollection does not implement events
- there is no function getElementsByClass()

View PostNtwiles, on 26 November 2010 - 12:44 PM, said:

To respond to your comments, the deletepost function is just unfinished. The parameter will be the id of the post to be deleted.

there are ways to get the table id without passing it explicitly, we can discuss that later.

View PostNtwiles, on 26 November 2010 - 12:44 PM, said:

As for the selectpost/deselectpost, really all they're changing for now is that when the user mouses over a post, a gray X should appear on the top right. When the user mouses over that X, it should turn black, and should be clickable to delete the post.

you can use a combination of background images (one on the table and one on the span). get the span in that corner (position: relative should do it). attach event to the span.
the span’s bg image is to appear when hoverd and must cover the table's bg image.

This post has been edited by Dormilich: 26 November 2010 - 06:24 AM

Was This Post Helpful? 1
  • +
  • -

#13 Ntwiles  Icon User is offline

  • D.I.C Addict

Reputation: 148
  • View blog
  • Posts: 830
  • Joined: 26-May 10

Re: Javascript String Appending

Posted 26 November 2010 - 06:26 AM

View PostDormilich, on 26 November 2010 - 05:11 AM, said:

won’t work.
- you must pass a function to the events, not a result of a function (unless that itself is a function)
- a HTMLCollection does not implement events


I don't understand exactly what you mean in your first point. As for your second point, is this more like what I need?:

function rollover()
{
   document.getElementsByClass('table_post').setAttribute('onmouseover', 'selectpost(6);');
}


I'm searching online for examples of this kind of thing but I'm not finding much luck:

View PostDormilich, on 26 November 2010 - 05:11 AM, said:

there are ways to get the table id without passing it explicitly, we can discuss that later.


It's actually the id of the post in the database that I was speaking of. Though that would come in very handy in what I'm about to do here it sounds like.

View PostDormilich, on 26 November 2010 - 05:11 AM, said:

you can use a combination of background images (one on the table and one on the span). get the span in that corner (position: relative should do it). attach event to the span.
the span’s bg image is to appear when hoverd and must cover the table's bg image.


The way I've done it with some help is to use a 32x16 image in a 16x16 span, then moving it over to display the second 'sprite' of the image. It seemed to work pretty well with the php. I'd be open using your suggestion though if it doesn't translate to javascript as well.

This post has been edited by Ntwiles: 26 November 2010 - 06:27 AM

Was This Post Helpful? 0
  • +
  • -

#14 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3572
  • View blog
  • Posts: 10,414
  • Joined: 08-June 10

Re: Javascript String Appending

Posted 26 November 2010 - 06:42 AM

problem #1:

document.getElementsByClass() should give you a syntax error (which usually leads to your whole script not to be read)

the correct function is named document.getElementsByClassName() (which is not supported by some browsers, but people have made work-arounds for that)

every document.getElementsBy*() method returns a HTMLCollection/NodeList. you can attach events only to Elements, document and window. any collection/list/array is out.

you have to attach the event to each member of the getElementsByClassName() method.

problem #3:
as I mentioned, you donít necessarily need a sprit. mind that there are 3 stages
- mouse outside table => no image
- mouse inside table & mouse outside span => gray image
- mouse inside span => black image

so at least 3 "images" are required, which you canít do by a 2-state action (hover/no hover)

thus, step one: no bg image on table and span
step 2: change bg image on table
step 3: change bg image on span, this must cover the still active bg image from step 2

something like
table, table span {
	background: none;
}
table:hover {
	background-image: url("gray.gif");
	background-position: top right;
}
span:hover {
	background-image: url("black.gif");
}

Was This Post Helpful? 1
  • +
  • -

#15 Ntwiles  Icon User is offline

  • D.I.C Addict

Reputation: 148
  • View blog
  • Posts: 830
  • Joined: 26-May 10

Re: Javascript String Appending

Posted 26 November 2010 - 05:37 PM

View PostDormilich, on 26 November 2010 - 05:42 AM, said:

problem #1:

document.getElementsByClass() should give you a syntax error (which usually leads to your whole script not to be read)

the correct function is named document.getElementsByClassName() (which is not supported by some browsers, but people have made work-arounds for that)

every document.getElementsBy*() method returns a HTMLCollection/NodeList. you can attach events only to Elements, document and window. any collection/list/array is out.

you have to attach the event to each member of the getElementsByClassName() method.

problem #3:
as I mentioned, you don’t necessarily need a sprit. mind that there are 3 stages
- mouse outside table => no image
- mouse inside table & mouse outside span => gray image
- mouse inside span => black image

so at least 3 "images" are required, which you can’t do by a 2-state action (hover/no hover)

thus, step one: no bg image on table and span
step 2: change bg image on table
step 3: change bg image on span, this must cover the still active bg image from step 2

something like
table, table span {
	background: none;
}
table:hover {
	background-image: url("gray.gif");
	background-position: top right;
}
span:hover {
	background-image: url("black.gif");
}


I see what you mean. I'm still having lots of trouble doing this. Ive tried both of the following:

function rollover()
{
   var tables = new Array();
   tables = document.getElementsByClassName('table_post');
   for (i=0;i<2;i++)
   {
      tables[i].setAttribute('onmouseover', 'selectpost(6);');
   }
}

function rollover()
{
   var tables = new Array();
   tables = document.querySelectorAll('table_post');
   for (i=0;i<2;i++)
   {
      tables[i].setAttribute('onmouseover', 'selectpost(6);');
   }
}



Both with one dimensional arrays and with two dimensional arrays because of this article. I always get the javascript error Uncaught TypeError: Cannot call method 'setAttribute' of undefined or a similar one though. Am I not accessing the elements of the array correctly?

This post has been edited by Ntwiles: 26 November 2010 - 05:37 PM

Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3