script inside scriptlet - bad practice how to avoid - java

i am working on a legacy project where i have seen below piece of code.
I know it is a bad practice to use script inside scriptlet.
Regarding this , i have few confusion in mind.
what i believe is scriptlet is executed before page loads, so if below if condition is true then ShowBookReference() function call is a part of an Html page, but my question is when page is rendered should this function call happens or not ?
<% if (refLinkTerm != null) { %>
<script Language="javascript">
ShowBookReference('<%=sub2ndNavMenu%>', '<%=refLinkTerm%>', <%=String.valueOf(searchType)%>, <%=String.valueOf(codeType)%>)
</script>
<%}%>
How to avoid this kind of practice ?
Please share your thoughts.

Use an MVC framework such as Spring MVC. In these frameworks, you fill in a Java object (or map of objects) with the values for the page to display, and then the page just fills in placeholders with those values.

In terms of JSP, Its usual to use scriptlets to assign value to JS.
But as you've mentioned that it runs before the page load, so it's good to run the function on window.onload.
<script type="text/javascript">
window.onload = function() {
ShowBookReference('<%=sub2ndNavMenu%>', '<%=refLinkTerm%>', <%=String.valueOf(searchType)%>, <%=String.valueOf(codeType)%>)
}
</script>
In case you're referring some DOM elements inside ShowBookReference function, it may not be available so run it on page load.
Else you can use UI frameworks like JSF which provides you tags to bind java values to UI easily.

Related

Which Strategy is Better To Use When Working With Push Notification In terms of performance And Efficiency?

Now that i have discovered the push technique in primefaces, I am wondering which of these two ways are better to use in terms of performance.
I am Creating a Dashboard in java with spring and primefaces.
Right now i have one channel for all dashlets, I am broadcasting a message alongside a uuid to all pages and each page is responsible to check if the the given uuid concerns it or not. If the answer is yes the page will do the desired action, like showing the message or just refreshing itself.
For example in almighty java :
pushContext.push("/refresh-chan", getUuid().toString());
and in XHTML side:
<p:socket onMessage="handleMessage" channel="/refresh-chan" />
<script type="text/javascript">
function handleMessage(uuid) {
var myUuid = '#{myBean.id}';
//console.log(myUuid + "-"+uuid);
if(uuid==myUuid)
{
//console.log("- I am refreshing myself : my id="+uuid);
location.reload();
}
}
</script>
But there is an other way to handle this in which i can create a separate channel for each dashlet and push the context for that dashlet alone:
Notice : The code is imaginary and it may not function:
pushContext.push("/refresh-chan"+getUuid().toString(),"may leave empty");
and in XHTML page (Yup! still imaginary) :
<p:socket onMessage="handleMessage" channel="/refresh-chan"+#{myBean.id} />
<script type="text/javascript">
function handleMessage(dummy) {
location.reload();
}
</script>
In addition to performance and efficiency consider that the code is part of a framework that i am building and other developers will have to write their own XHTML pages and then add the XHTML part of the code(demonstrated above) in their pages too, so it should be easy for them to understand what is happening .
thank you

Passing json object via ajax from jsp to javascript

How can pass json values from jsp to javascript as object via ajax?
I can not use global js variables in jsp because this will lead to json content to be visible in page's source
Here is the scenario that I want to achieve:
url of jsp is opened in browser.
Data is being created in scriptlet and coverted to JSON format
json is "sent" to javascript as object
From above scenario, i understand that javascript must initiate the ajax call to jsp.
The issue with this, that jsp's code will be invoked 2 times:
When page is opened in browser - data is prepared
on each ajax call same code will be called again
Constrains: No jquery, no other libs, no servlets, no additional jsps. :(
EDIT:
There is additional problem, I need to pass multiple json objects to javascript.
I wont be able to do it with response.getWriter().write();
I don't think concatenating all json objects and sending is the correct solution.
The parsing of the received object in javascript http.responseText will be overwhelming.
Why do you need ajax here? If you know that you need to populate some things from server onto jsp page you can do that through scriplets itself:
EX
<%# page import="com.mypackage.PersonDAO" %>
<html>
<body>
<table>
<th>Name</th><th>Email</th><th>Contact</th>
<%
List<Person> myList = PersonDAO.getAllPersons();
for(Person person:myList)
{
%>
<tr>
<td><%=person.getName()%></td>
<td><%=person.getEmail()%></td>
<td><%=person.getContact()%></td>
</tr>
<%}%>
</table>
</body>
</html>
This is a very simple example. You can do more complex things using JSTL.. :)
So there is no jquery, no Servlets, no ajax and no extra jsp's :)
UPDATE
Since you want data in your javascript before page loads you can use jQuery's holdReady() method.
$.holdReady( true );
$.get( url, function() {
// Perform something
$.holdReady( false );
});
See but all modern browsers have developer tools like firebug for mozilla, so any ajax call made will be trapped by them. The only way you can secure them is my encrypting them.. which will complicate things for you... IF you can explain the scenario you are trying to implement may be I can come up with it..

GWT: How to make sure a javascript is run after the GWT page is constructed

I have a javascript file main.js. The main.js contains something like this:
$(document).ready(function() {
Cufon.replace('#myform p.head', { fontFamily: 'HelveticaNeueLT Std Thin' });
......
});
I suppose what this does is to run this method after the whole page is loaded and apply the change to the css elements.
But what I found out is that this only works when the script is loaded before all the HTML elements, e.g.:
<body>
HTML......
<script type="text/javascript" src="js/main.js"></script>
</body>
However, if this script is put on top of all the HTML, it stops working:
<body>
<script type="text/javascript" src="js/main.js"></script>
HTML......
</body>
This happens on both static HTML and the GWT page. Because my GWT always put the generated HTML stuff at the end of all the body contents, the script is always before the HTML, hence is does not work. For example, my HTML for GWT module is like this:
<body>
<script type="text/javascript" src="js/main.js"></script>
</body>
And after compiled, the generated HTML from my UIBinding gives HTML page like:
<body>
<script type="text/javascript" src="js/main.js"></script>
Generated HTML....
</body>
My questions are:
Is there anyway in GWT where I can specify the generated HTML goes
between some statements in the tag.
Is there any other ways instead of $(document).ready I can guarantee
it is called as the last thing happened in a page load?
Many thanks
While I find it strange that the script doesn't work as intended when moved up in a static page ($(document).ready(…) is supposed to wait for the </html> to be reached –aka DOMContentLoaded– before running the function passed to it), it's not the reason it doesn't work with your GWT application (in other words, your diagnostic is wrong).
GWT's onModuleLoad also runs at DOMContentLoaded (or later, but never earlier) so you probably have a race condition between your app's onModuleLoad and jQuery's $(document).ready(…). You could try putting the <script> for your GWT app before the main.js, but because onModuleLoad might run after DOMContentLoader anyway, there's no guarantee it'll work (even less in a crossbrowser way).
I think you'd better remove the main.js or replace the $(document).ready(…) with a simple function, and call Cufon (and/or whatever else you were doing in $(document).ready(…)) from within your GWT app, at the moment appropriate for your needs (i.e. after you attached the #myform p.head element/widget to the document).
The easiest way to do that is to put the script in a JSNI method and then call that method where appropriate. Just make sure you use $wnd.Cufon instead of Cufon (and similarly for all other globals), and replace all occurrences of document with $doc and window with $wnd.
public static void cufon() /*-{
$wnd.Cufon.replace('#myform p.head', { fontFamily: 'HelveticaNeueLT Std Thin' });
}-*/;

What is the best way of java and javascript interaction?

Excuse my lack of knowledge in many fundamental areas, but I am just learning how to create applets in java and how to allow interaction between the applet and the web page (javascript).
At the moment I have an applet with an init() and method1(). method1() just returns a string.
The applet is loaded on a web page and in javascript I literally reference the function:
<html>
<head>
<title>Testing Applet</title>
<script>
function hello() {
result = document.wplayer.method1();
alert(result);
}
</script>
</head>
<body>
<applet code = "player.Player" name = "wplayer" archive = "player.jar" width = "600" height = "400">
</applet>
<button onClick="hello();">Interact with app</button>
method1() just returns a string ("blah blah blah");
My question is, is this a safe way to do it and is it the most compatible?
Thanks!
Nick
is this a safe way to do it and is it the most compatible?
It's only as safe as the client is safe, so you should assume that the client may edit/forge/hack, etc.
If you meant safe in the other sense - not causing conflict - use an Object as your namespace in JavaScript and have everything kept within that Object. This way you are much less likely to have trouble with any conflicting variable names elsewhere on a page. You may also want to use unobtrusive JavaScript, to keep your script and HTML independent of each other.
Currently, your function hello is in the global namespace, and creates a global result, which could cause conflicts.
Assuming that the client has an up-to-date copy of Java and plugins enabled, you only really need to worry about the same compatibility issues as when writing any normal JavaScript for any browser.

google.load issue

Hi I am messing around with google ajax api at the momemt and following the examples from the documentation I have two script tags in my html file:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script language="Javascript" type="text/javascript">google.load('search', '1');</script>
All works fine, but it will not work when I am using jquery and trying to call the google.load('search', '1'); in an external javascript file after $(document).ready(function()
I get the following error: null is null or not an object.
I am obviously missing something fundamental as I am just learning javascript but I was under the impression that it is best to use javascript unobtrusively. The second script tag that actually contains some js code isnt unobtrusive. Can anyone lend any help with this please?
From what you have explained it seems your page is setup something like this:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load('jquery');
$(document).ready(function(){
... do stuff ...
});
</script>
<script src="/my/external.js" type="text/javascript"></script>
However, this will not work as you expect since the document.ready event will not fire until the DOM is completely loaded. JavaScript files, however, are executed as they are loaded. So the actual execution looks like this:
Load Google JSAPI
Load jQuery
Load External.js
Call Document Ready
Depending on what the rest of your code looks like, you might want to either put all your initialization code in a separate file, or move your search load back into the main document.
ABOUT UNOBTRUSIVE CODE:
David, unobtrusive JavaScript has to do with how it affects the page, not with whether or not it is in-page or external.
It is more about not making your site so dependent on JavaScript that it does not function with it disabled
For instance, this is obtrusive:
Click Me
Because it will only work with JavaScript enabled. Additionally the code is inline which is bad because it does not separate functionality from structure (HTML).
However, taking a similar piece of code:
Click Me
and using this javascript/jquery snippet:
$(document).ready(function(){
$("#do-something").click(function(e){
doSomethingNicer();
e.preventDefault(); // Keep the browser from following the href
});
});
Is becomes unobtrusive because the page still works (loads /do/something by default), but it works in a nicer way when JavaScript is enabled (executes the javascript instead of loading that url). This is also called Progressive Enhancement.

Categories