Wednesday, December 23, 2009

Using different JQuery versions in the same page

Suppose your web page in the CMS is already using one version of jquery and you want to add a new HTML element with a javascript library that needs a more recent version of jquery.

You may think to use the google api like:

<script>
google.load("jquery", "1.3.2");
</script>



and then use the noConflict option like:




<script>
function OnLoad(){
jq13 = jQuery.noConflict(true);
}

google.load("jquery", "1.3.2");
google.setOnLoadCallback(OnLoad);
</script>



Unfortunately this will not work correctly in IE…so you may want to use the technique to dynamically load a javascript (see http://themnd.blogspot.com/2009/12/dynamically-load-javascript-on-webpage.html)






<script>
function OnLoad(){
jq13 = jQuery.noConflict(true);
}

function loadJQuery() {
loadJS('http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js', function() {
OnLoad();
});
}

jQuery(document).ready(function() {
setTimeout(function() {
loadJQuery();
}, 2000);
});
</script>



at this point you can load the needed library in the OnLoad function before setting the noConflict option. Please note that we are still using the google cdn to fetch the jquery library. The OnLoad function would be something like:




function OnLoad(){
loadJS(plugin_url, function() {
jq13 = jQuery.noConflict(true);
// now you can call the plugin methods here:
jq13.XXXX()
});
}

Dynamically load javascript on a webpage

When you work with a CMS sometimes you may need to dynamically add a javascript library on the fly.

The easiest thing to do is:

var headID = document.getElementsByTagName("head")[0];         
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = url;
headID.appendChild(newScript);



But what if you want to be notified when the javascript has been loaded? You can add the onload parameter:




newScript.onload = function(){
func();
};



but you will find out that this will not work in IE, so what you really need to use is:




function loadJS(url, func) {
var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
if (newScript.readyState) { //IE
newScript.onreadystatechange = function() {
if (newScript.readyState == "loaded" || newScript.readyState == "complete") {
newScript.onreadystatechange = null;
func();
}
};
} else { //Others
newScript.onload = function(){
func();
};
}
newScript.src = url;
headID.appendChild(newScript);
}



We will rely on the onreadystatechange event that IE will fire, unfortunately that event is, in reality, the progress of the loading and sometimes it reach the “complete” state, sometimes only the “loaded” state, so if we really want to be sure that our callback will be called we have to get the first one and then cancel the event.



You can learn more at: http://www.nczonline.net/blog/2009/06/23/loading-javascript-without-blocking/



In a similar way you can also dynamically load CSS:




function loadCss(url) {
var headID = document.getElementsByTagName("head")[0];
var cssNode = document.createElement('link');
cssNode.type = 'text/css';
cssNode.rel = 'stylesheet';
cssNode.href = url;
cssNode.media = 'screen';
headID.appendChild(cssNode);
}

Saturday, October 03, 2009

Tuesday, August 18, 2009

Creating an HTML layout that is cross browser x Dummies

This post is mostly for who have to use an HTML template generated by an external Web designer and making it “dynamic”, that means we are handed the html page and we have to create the template that will be used by a web application to render content using that templates like polopoly (www.atex.com) but it is also true for other systems like joomla.

1. do not use cellpadding and cellspacing in tables, set them to 0 and eventually use CSS to control spacing, firefox, chrome and internet explorer interprets them differently.

2. do not use SPACER tag since internet explorer will not understood it, use a transparent 1 pixel gif with an img tag instead.

3. do not comment a css line with // since internet explorer will read it anyway, comment using /* and */ if you really need to.

4. if you start doing evaluate the layout with internet explore it would be more easy to adjust it for firefox and chrome (if any adjustment needs to be made).

5. always start with IE6 if you need to target it since it is the poorer browser that probably will need more care.

Wednesday, August 05, 2009

How to execute a command line tool from a servlet

In a java program when you want to execute an external program you will normally write something like this:

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
proc.waitFor();


Where cmd is the command line needed to be executed.



However, if you run the same piece of code from a tomcat servlet it may just hung up until you kill it. The problem is documented in the documentation of the exec method, you need to consume the inputStream and the outputStream, so a quick way of doing it is to start other two threads that will consume those stream.



First create the thread class that will process the stream:



class StreamGobbler extends Thread
{
InputStream is;
String type;

StreamGobbler(InputStream is, String type)
{
this.is = is;
this.type = type;
}

public void run()
{
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null) {
System.out.println(type + ">" + line);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}



Now we can modify the previous code to handle InputStream and ErrorStream:



Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
StreamGobbler errorGlobber = new StreamGobbler(proc.getErrorStream(), "CMDTOOL-E");
StreamGobbler outputGlobber = new StreamGobbler(proc.getInputStream(), "CMDTOOL-O");
errorGlobber.start();
outputGlobber.start();
proc.waitFor();


et voilĂ  the code will execute just fine in a servlet.



The idea and code has been taken from: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1

Thursday, July 23, 2009

Apache mod_proxy and tomcat

If you use apache to forward request to a local running tomcat, you may encounter this error message in the error.log:

[error] (13)Permission denied: proxy: HTTP: attempt to connect to 127.0.0.1:8080 (*) failed


If you have SELinux running you have to check if it allows local connections, by running:



getsebool -a | grep httpd


you have to check that the following is written:



httpd_can_network_connect –> on


if it is off, you have to enable it:



setsebool -P httpd_can_network_connect=1


and restart your apache.



This tip has been taken from: http://swapyourbooks.com/welcome/knowledgebase/misc/selinux-allow-httpd-tomcat-proxy.html