JavaScript inside jstl iteration - javascript

I have the following codes:
<%int number=0;%>
<c:forEach var="row" items="${tAdmin.rows}" varStatus="totalRow" step="1">
<td><%=++number%></td>
<td>
<div id="content" style="table-layout:fixed; width:405px; word-wrap:break-word;">
<script language="JavaScript" type="text/JavaScript">
function load(){
var content='${row.content}';
document.getElementById("content").innerHTML=content;
document.getElementById("content").innerHTML=Utf8.decode(document.getElementById("content").innerHTML);
}
window.onload=load;
</script>
</div>
</td>
</c:forEach>
The problem is that it only shows the result of the last content instead of printing it out line by line according to number.

What you are creating, if you view the page source in the browser, would look something like this (note the ${row.content} will have already been replaced on the server):
<td>0<td>
<td>
<div id="content" style="table-layout:fixed; width:405px; word-wrap:break-word;">
<script language="JavaScript" type="text/JavaScript">
function load(){
var content='The first row content';
document.getElementById("content").innerHTML=content;
document.getElementById("content").innerHTML=
Utf8.decode(document.getElementById("content").innerHTML);
}
window.onload=load;
</script>
</div>
</td>
<td>1<td>
<td>
<div id="content" style="table-layout:fixed; width:405px; word-wrap:break-word;">
<script language="JavaScript" type="text/JavaScript">
function load(){
var content='Some different content';
document.getElementById("content").innerHTML=content;
document.getElementById("content").innerHTML=
Utf8.decode(document.getElementById("content").innerHTML);
}
window.onload=load;
</script>
</div>
</td>
<td>2<td>
<td>
<div id="content" style="table-layout:fixed; width:405px; word-wrap:break-word;">
<script language="JavaScript" type="text/JavaScript">
function load(){
var content='Yet some more content';
document.getElementById("content").innerHTML=content;
document.getElementById("content").innerHTML=
Utf8.decode(document.getElementById("content").innerHTML);
}
window.onload=load;
</script>
</div>
</td>
You're going to have many copies of function load() and many times where window.onload is assigned window.onload=load;
When this arrives at the browser and is interpreted, only the last definition of function load() will be in effect; only the last time you assign window.onload=load; means anything (because you keep replacing the value of window.onload) -- each redefinition of load() will replace the previous one - so only your last var content='${row.content}'; is ever executed.
In addition, you will have many <div> tags with the same id of "content" and that's not allowed.
The content of each of those <td><div>...</div></td> blocks can be set by the JSP/JSTL itself on the server -- there is no need to set the innerHTML via javascript.
You can use the totalRow varStatus that you set up to provide the number for the first <td> -- you don't need to increment your own counter.
You can use Expression Language (EL) to access the content value of each row.
Inline style="blah blah blah" sucks. Use that only if absolutely necessary.
Instead, put all this style in CSS targeting .contentbits:
style="table-layout:fixed; width:405px; word-wrap:break-word;"
becomes
.contentbits {
table-layout:fixed;
width:405px;
word-wrap:break-word;
}
The page fragment becomes much simpler:
<c:forEach var="row" items="${tAdmin.rows}" varStatus="totalRow" step="1">
<td>${totalRow}</td>
<td>
<div class="contentbits">${row.content}</div>
</td>
</c:forEach>

It's not the right way to do it, but a simple solution would be use addEventListener instead onload:
<%int number=0;%>
<c:forEach var="row" items="${tAdmin.rows}" varStatus="totalRow" step="1">
<td><%=++number%></td>
<td>
<div id="content<%=number%>" style="table-layout:fixed; width:405px; word-wrap:break-word;">
<script language="JavaScript" type="text/JavaScript">
window.addEventListener("load", function () {
var element = document.getElementById("content<%=number%>");
element.innerHTML=Utf8.decode('${row.content}');
}, true);
</script>
</div>
</td>
</c:forEach>
In fact your code is using only the last "onload" because, when loading the page, it will execute the javascript load callback only when finish full loading it. So, each time you loop is executed, it updates the load callback reference for the last one, so when onload is triggered, the last only will be executed.
But your code has other errors too. The content id, repeats at the code lot of times, that will make your div getElementById useless, because you have lot of ids that are equal. Ids must be unique to work property.
To finish, it's not a good pattern to mix your HTML with scripts inside, is better to have you logic file (javascript file) outside, then it can make changes in your code when finish to load, reading the html that was generated. You also can create data attribute in your div then read it by the javascript to manage all itens with a specific data attributes.
To keep it simple, I will add an example:
<%int number=0;%>
<c:forEach var="row" items="${tAdmin.rows}" varStatus="totalRow" step="1">
<td><%=++number%></td>
<td>
<div id="content<%=number%>" style="table-layout:fixed; width:405px; word-wrap:break-word;" data-content="${row.content}">
</div>
</td>
</c:forEach>
Now the script file (I'm using jQuery for this example works on any browser):
$(function() {
$("[data-content]").each(function(item) {
$(item).html(Utf8.decode(item.attr('data-content')));
});
});

Related

Modifying a function from onclick to onload

I am very new to javascript and .net fremework. Please help me with this issue.
Here is the small snippet of my code, and I am displaying a table onclick, but I want it to display on page load.
I have tired window.onload, Placed the code in tag, placed it in $(documen).ready() but none of them are working, can someone please let me know what are to be modified in order to display the table on page load instead of onclick?
Here is my code snippet:
<tr id='group11' class="group1" rel="<%# Eval("RowCount") %>">
<td colspan="6" class="description first">
[-]
<a href="javascript:CallDialog('<%# Eval("SummaryMessage") %>');" style= "background-color:yellow">RI [<font size="2"> <i> <%# Eval("LastRI")%> </i> </font>]
</a>
</td>
Thank you
the usual pattern if you want to wait till the DOM elements are ready is:
document.addEventListener('DOMContentLoaded', init);
function init(){
$('myElement').text('Do Stuff with the page')
}
As an aside: I consider it an antipattern to template your scripts, as you're doing with onclick="toggleCategory('#group11',<%# Eval("RowCount") %>);
My preferred solution would be to always execute the same script for all requests.
In your case you might place one element on the page for each item and use that instead of the templated rowCount:
function toggleCategory(id, count){
...
};
var count = $('#group11 .myItem').length
toggleCategory('#group11', count)
Or instead you could pass data from the .NET server to the javascript by adding it to the DOM:
<body data-group11count="<%# Eval("RowCount") %>">
...
</body>
function toggleCategory(id, count){
...
};
var count = $('body').data('group11count');
count = Number(count);
toggleCategory('#group11', count)

Javascript : How to access a table inside a frame?

To access the value of an ID we can use :
document.getElementById(ID).value.
But I have a problem of accessing an ID in a table. There is a frame inside a table. The content of the frame is a table also because I want to scroll up and down the table.
main.html :
<script type="text/javascript">
function show_name()
{
alert(document.getElementById("name1").value);
}
</script>
<table id="table1">
<tr>
<td>
<div id="mydiv">
<!-- the ajax func call myframe.php and pu result here -->
</div>
</td>
</tr>
</table>
<input type="button" value="Show Name" onClick="show_name()">
myframe.php :
<iframe height="500px" height="400px" src="table2.php"></iframe>
Below is table2.php. It produces a table interactively based on a parameter passed into it. And of course the feedback inserted into "mydiv".
<?php
// mysql_connect();
// mysq_query....
?>
<table id="table2">
<tr>
<td>
<input type="text" id="name1" value="john">
</td>
</tr>
</table>
The code run very good, and everything come up into the page correctly. By I want to do someting with an object inside the frame, but how to access it ?
So far pushing the button give nothing, that means the object can not be accessed by the code. Of course, there will be more meaningfull process rather than just alert a name.
Thanks for help.
To access the element inside the iframe:
window.frames[1].document.getElementById('name1');

Pass to javascript variable attribute from html input id="attribute"

Input
<input type="text" value="" id="row1">
<input type="text" value="" id="row2">
Need to get last character from row and pass it to javascript variable. Here is row1 and row2, need to get variables 1 and 2
I try to use this, but does not work
$('[id^="row"]').each(function (index, row) {
var row = row.id.substring(3);
alert (row);//this is only to check if value exists (alert or not)
});
No alert at all. But need: on first iteration (.each) var row is 1, on second, - 2, etc.
Used this as example. The example works, but my code not
$.each([52, 97], function(index, value) {
alert(index + ': ' + value);
});
Your code works fine, provided that:
You are actually including jQuery at some point (you didn't mention it in your question, but you appear to be using it)
You run the code after the elements exist.
Here's your code with jQuery included and where we ensure that the code doesn't run until after the elements exist: Live Copy | Live Source
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<input type="text" value="" id="row1">
<input type="text" value="" id="row2">
<script>
(function($) {
$('[id^="row"]').each(function (index, row) {
var row = row.id.substring(3);
alert (row);//this is only to check if value exists (alert or not)
});
})(jQuery);
</script>
</body>
</html>
Note how the script tag is after the elements it operates on, so they exist when that script runs.
This would not work:
<script>
(function($) {
$('[id^="row"]').each(function (index, row) {
var row = row.id.substring(3);
alert (row);//this is only to check if value exists (alert or not)
});
})(jQuery);
</script>
<input type="text" value="" id="row1">
<input type="text" value="" id="row2">
...because when the script runs, the elements don't exist yet.
If for some reason you're not in control of where the script element goes, you can use jQuery's ready function to wait to run your code until the DOM has been loaded. But there's no need to do that if you control where the script tags go, just put them at the end of the document, just before the closing </body> tag.
More:
YUI Best Practices for Speeding Up your Website
Google Closure Library engineers on when DOM elements are ready

Table Refresh, Every Second

<html>
<body>
<body bgcolor="33FF00">
<script language = "JavaScript">
//-----------------Created Variables Here------------------
timeLeft = 30 //this is counted down from until it hits 0
points = 0 //this is the points system that is added to by 10 each time a duck is clicked
// ----------------Duck Or Sky element-----------------
function duSky(){ //This is a function to tell add points to the points variable if the user clicks a duck.
duckNum = Math.floor((Math.random()*10)+1)
if(duckNum<10){document.write("<img src=images/skyTile.jpg>")}
else{document.write("<img src='images/duckTile.jpg' onClick='duckClick()'")}
}
</script>
<center><img src=images/duckHuntTitle.gif><br> <!Duck Hunt title gif, no background so you can see the background of the page, also centered>
<div name = "tableDiv"> <!Named the table "TableDiv" so that I can refer to it at a later date. This was to try and make my job of refreshing easier>
<table>
<tr>
<td> <script> duSky() </script> </td>
<td> <script> duSky() </script> </td>
<td> <script> duSky() </script> </td>
<td> <script> duSky() </script> </td>
<td> <script> duSky() </script> </td>
</tr> <!Inside of all the table boxes there is a function that designates whether inside will be a duck or sky tile>
<tr> <!This is the duck table that is exactly 1000px wide by 400px height. This is created by 10 200px by 200px boxes, two rows of 5 boxes>
<td> <script> duSky() </script> </td>
<td> <script> duSky() </script> </td>
<td> <script> duSky() </script> </td>
<td> <script> duSky() </script> </td>
<td> <script> duSky() </script> </td>
</tr>
</table>
</div>
<form name="score">
Points <input type="text" name="pointsscored" readonly="readonly"> <!This is the box that is centered that displays the points the player has got, also is now readonly so no tweaking is allowed>
</form>
<form name="timer">
Time <input type="text" name="timeBox" readonly="readonly"> <!This is the timer box that is centered as well that displays how long the player has left and is readonly>
</form>
</center>
<script language = "JavaScript"> //Returns the script to JavaScript to allow for functions to be used that are related to the HTML previous to this
document.timer.timeBox.value = timeLeft //Displays the time left before the game has even started and been clicked so the player immediately knows the time that they have to play with
function timeDecrease(){ //This is the timer function that reduces the timer by a second each time to make the game slowly time out after 30 seconds
setInterval(function(){timeLeft-- //I am still working on the refresh function but hopefully it will be corrected to make the table refresh with every 1000 miliseconds
document.timer.timeBox.value=timeLeft;
//document.tableDiv.reload(true) //trying to get the reload function to work.
},1000); //1000 miliseconds, therefore it is 1 second
}
while(timeLeft < 0){alert("Timeeeeeees Up, you scored: ", points ,"points! well done Duck Slayer!")} //Alert to signify the end of the game.
// ----------------Function for clicking the duck-----------------
function duckClick(){
points = points + 10;
document.score.pointsscored.value = points; //when the player clicks the duck, points will be added to the points box
}
</script>
<center>
<form name = "playButton">
<button type="button" onClick = "timeDecrease()">Play!</button> <!This is the on click function that starts the game/countdown feature>
</center>
</form>
</body>
</html>
I have a problem with getting my graph to work. I am currently working on making a simple point and click game and I need the table to refresh to make the images become randomized in the position. The idea is that it refreshes every second, giving the appearance of true randomization from a previous section of the script. The problem is that I can't get the table to refresh even though I have set a div tag and I am using the reload function. I am hoping that you can help me find a solution to this.
Also the website doesn't recognise the document.tableDiv.reload(true) part but I don't understand how to get the table to refresh with every second that goes past.
P.S if you haven't guessed I am awful at coding but hope to get better.
Use jQuery, it will make your life easier as selectors mean you won't have to repeat so much code.
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
Assign all of the td elements to run duSky() function in a class -- we'll also take the script out of the td as we're going to run it from jQuery's document.ready function:
<td class='dusky'></td>
Next, we make a function to assign each td with the output of duSky():
<script>
// This function takes every table cell with dusky class and inserts output of duSky() into it
$(document).ready(function refresh(){
$('.dusky).each(function(){
this.html = duSky();
})
})
</script>
Finally, we make it refresh every 5 seconds:
<script>
// Make our refresh script run every 5 seconds
setInterval(refresh, 5000);
</script>
Note: I can't test this where I am, code may not be 100% correct, but this is on the right lines. If you change it and it helps, please give me the right code so I can edit the post and give future readers an easier ride.

Control not reaching to .js function

In my following code, I am calling function "Make Request" that is located in a separate .js file. But the control is not reaching to this function. I have also added the link to the related file.
<link rel="section" href="../Lib/ajaxhandler.js" type="text/javascript">
<td oncontrolselect="MakeRequest('inCategory','SELECT * FROM electioncategorymaster', 'ecid', 'ecname');">
<select id="inCategory" name="inCategory" class="entryFormInputBoxColor">
</select>
</td>
I want to make a call to the MakeRequest function when page is rendered. On which event I must call the function?
Your link to the script is wrong. The link tag is useful for e.g. stylesheets.
Your script tag should be like this:
<script src="../Lib/ajaxhandler.js" type="text/javascript"></script>
Also, you may want to catch the oncontrolselect event of the combo box instead of the td.
How about this...
<script src="../Lib/ajaxhandler.js" type="text/javascript"></script>
<td>
<select id="inCategory" name="inCategory" class="entryFormInputBoxColor"
onChange="MakeRequest('inCategory','SELECT * FROM electioncategorymaster', 'ecid', 'ecname');">
</select>
</td>

Categories

Resources