Modifying a function from onclick to onload - javascript

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)

Related

Call Javascript Function from .ascx file

I have one javascript function named 'change2()' which is define in .ascx page's script tag.
I want to call that function from onclick event of img tag (Note : img tag is also on the same page).
It is compulsory to use img tag only for image.
I tried all the below ways, but unfortunately It doesn't work for me.
Test.ascx
<script language="javascript" type="text/javascript">
function change2() {
alert("Hi");
}
</script>
<table>
<tr>
<td class="list">
Most liked
</td>
<td>
<img id="imgLkU" src='<%# WebHelper.GetBaseURL(Request) + "/images/slide_btn_down.png"%>'class="icon_right_panel" runat="server" onclick="change2();" alt="Slider" />
</td>
</tr>
</table>
Second Way :
<table>
<tr>
<td class="list">
Most liked
</td>
<td>
<img id="imgLkU" src='<%# WebHelper.GetBaseURL(Request) + "/images/slide_btn_down.png"%>'class="icon_right_panel" runat="server" alt="Slider" />
</td>
</tr>
</table>
Please give me your suggestions to call javascript function from same page.
As I can see, the img id is imgLkU, so, instead of including the call in the img tag itself, you can subscribe the event "from the outside", i.e. do it like using $.on, (or $.click) like this:
$.on('click','#imgLkU', function() { change2(); });
// or equivalent $.on('click','#imgLkU', change2);
or
$.('#imgLkU').click(function() { change2(); });
// or equivalent $.('#imgLkU').click(change2);
Do it right after defining change2 in the same script tag.
I'd also recommend you doing the change2 definition and the event subscription inside an inmediately invoked function expression to avoid polluting the global javascript namespace.
(function() {
// define and subscribe here
})();
Because your elements all have runat="server", their onclick property is reserved for a backend-code actionlistener which will be executed at postback.
the onClientClick property is reserved to allow you to still attach javascript "listeners" to what is considered the client-side onclick.
keep in mind that returning false from an onClientClick handler will prevent postback from happening if an onclick listener is also hooked up. (onClientclick is executed before initiating the postback)
try this :
<img id="imgLkU" src='<%# WebHelper.GetBaseURL(Request) + "/images/slide_btn_down.png"%>'class="icon_right_panel" runat="server" onclientclick="change2();" alt="Slider" />
The following function can be directly called from document.ready function like
$(function () {
$('#imgLkU').click(function () {
//do what ever you want
})
});
First, take out the runat="server" on your image since you are already using server tags to set the url. If you still want to use runat="server", you can either:
1: change your img into an <asp:Image> tag and use ImageSource instead of src and OnClientClick instead of onclick.
2: set the src attribute in the code behind.
After that, any click method - from your question to all the answers - should work.
If that still does not show the alert, then start taking out code until it does and work your way from there...

Meteor not adding a new plugin element in a for each

I have a table where one of the columns is a Bootstrap Switch element which will be later used to turn on or off the corresponding element of that row.
<tbody>
{{#each sensorslist}}
<tr>
<td>{{name}}</td>
<td>{{mac}}</td>
<td>
<input type="checkbox" class="on-off-checkbox" checked={{state}} />
</td>
</tr>
{{/each}}
</tbody>
However, if I hard code one row, it all works great and the switch always appears. However, when I load from the sensors list in my database as shown, it only shows when I go to that page by a link (I am using Iron Router). If I press F5, it not shows the Bootstrap Switch.
I am not using autopublish. I am subscribing to the sensors collection in the client:
Sensors = new Mongo.Collection("sensors");
Meteor.subscribe('sensors');
And to load the data I use this helper:
Template.sensores.helpers({
'sensorslist': function(){
return Sensors.find();
}
});
And also to render the elements I have this as the rendered function:
Template.sensores.rendered = function (){
$('.on-off-checkbox').bootstrapSwitch({
'offColor': 'danger'
});
};
As I said, if I move around the webapp using only the menu, it works fine, if I refresh the page with F5 or simple go to that page using a direct link it will not work.
I noticed that if I use a setTimeout to execute that code inside the rendered, and add a sufficient amount of time, it will always work, so I guess I am missing something...
Thank you very much in advance!
I had encountered the same issue as yours ever before.
As I know, when Template.sensores is rendered, the data context sensorslist is not loaded completely so we can't query the DOM under sensorslist block.
But when you use setTimeout for a sufficient amount of time, it works as the DOM under sensorslist is rendered completely.
My solution for this is using another template additonally:
template(name='sensores')
...
<tbody>
{{#each sensorslist}}
{{> sensorsList}}
{{/each}}
</tbody>
...
template(name='sensorsList')
<tr>
<td>{{name}}</td>
<td>{{mac}}</td>
<td>
<input type="checkbox" class="on-off-checkbox" checked={{state}} />
</td>
</tr>
The Bootstrap Switch is placed in the rendered function of sensorsList template.
Since this template will be rendered as many times as the data context sensorslist's length, each DOM we want to manipulate should be scoped within its own template instance.
Template.sensorsList.rendered = function () {
this.$('.on-off-checkbox').bootstrapSwitch({
'offColor': 'danger'
});
};

call innerHTML based on a condition from jsp code in spring mvc

I am trying to find a way to have the document.getElementById("1").innerHTML to get triggered based on a condition coming from jsp code.
For example I have the following jsp code on the jsp page,
<table border="1">
<c:forEach items="${elements}" var="element">
<tr>
<td>${element.elementNumber}<br /> ${element.isReserved}
</td>
</tr>
</c:forEach>
</table>
Based on "element.isReserved", I need to change an element (supposedly using .innerHTML)in html. The element in html looks like the following. I have several of these elements.
<div class="col-xs-2">
<div class="o-btn">
<a id="1" onClick="myFunction(this);">1</a>
</div>
<div class="clearfix"></div>
</div>
As shown above, it is displayed as a button with value "1". I want to change the value to "X" based on a condition. I can do this directly with js,
<script>
function myFunction(elmnt) {}
function isReserved() {
return 'X';
}
document.getElementById("1").innerHTML = isReserved();
</script>
But I need to make it dependent on the output from spring or the jsp code shown above. My desired output is that the "1" displayed on the button will change to a "X" when the element.isReserved() (inside the jsp code) evaluates to true. Since I have several of the button elements, I need to check for every button if element.isReserved() evaluates to true.
I was able to make it work. I found this article very helpful.
After understanding (and accepting reality) how JSP works with html, I had to slightly restructure my program.
From spring mvc, I added my variables to the model,
model.addAttribute("element1", 1);
On the jsp page I checked the variables with javascript,
if("${element1}" == 1) {
document.getElementById("1").innerHTML = 'X';
document.getElementById("1").style.color = 'red';
}
Probably there are better solutions, but for a newbie like me, it works great!
The article I mentioned above is indeed a good and important read for new comers.

Print each loop of <c:foreach> individually using javascript

Currently I'm printing the whole page with print icon using following code:
<a href="javascript:window.print()">
<img src="images/printIcon.gif" alt="Print the Records" width="40" height="40" border="0" />
</a>
I am reading a list of objects in JSP and displaying the object details using <c:foreach>.
I want to display a print icon beside details of each object and print(to external printer) that individual object details only, when clicked on it. The whole page is in single div.
I'm not sure whether this can be done or not. Can I control the each loop using some sort of ID?
Edit:
Example:
<c:forEach var="case" items="${distributions}">
<table>
<tr>
Print case details
</tr>
</table>
</c:foreach>
If I have 10 distributions, I get 10 tables so want a print icon beside each table and when clicked on it, print that individual table only.
I have not done the following but theoretically it should work:
1) define a print stylesheet, with:
body.detail-print .detail-item{display:none}
body.detail-print .detail-item.current{display:block}
2) define an event listener, e.g. with jQuery
$(".detail-item .print").click(function(e) {
$("body").addClass("detail-print");
$(this).closest(".detail-print").addClass("current");
window.print();
});
This should only print what is visible in your print stylesheet.
The only problem I see here: If someone wants to print the whole page afterwards, the browser will only print the last selected item. You could use a setTimeout to reset the classes. I have no better idea for now...
In your block you could put the data in a td then use the method described in this post to print the contents of that td.
<script type="text/javascript">
$(function(){
$(".printable").each(function(){
var $td = $(this);
var $printIconTD = $('<td><img src="images/printIcon.gif" alt="Print the Records" width="40" height="40" border="0" /></td>');
$td.parent().append($printIconTD);
$printIconTD.click(function(){
Popup($td.html());
});
});
});
</script>
....
<c:forEach var="case" items="${distributions}">
<table>
<tr>
<td class="printable">Print case details</td>
</tr>
</table>
Only problem with this solution is god and everyone has pop-ups disabled, so you will have to put a notice of sorts on the page letting users know
A different way to what has been suggested would be to reload the page showing only the selected object and then call the printer dialog (e.g. on document load). So the printer icons next to the objects could link to the same page and pass it a parameter that you'll be printing and the ID of the object that you want to print.

JavaScript inside jstl iteration

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')));
});
});

Categories

Resources