Images, CSS and AbstractJavascriptComponent

Hi there,

I have a simple javascript component that is using a javascript and a stylesheet file. From the stylesheet it is retrieved an image but this image is not loaded and I don’t understand why.

Here the use case (it is more simple than mine but you could reproduce the same problem).

The server side component:


@JavaScript({
"jsdiv.js"	
})

@StyleSheet({
"jsdiv.css"
})
public class JSDiv extends AbstractJavaScriptComponent {
	
	public JSDiv(){
		setStyleName("myelement");
		
		JSDivState state = getState();
		state.value = "Hello world";
	}
	
	
	@Override
    public JSDivState getState() {
        return (JSDivState) super.getState();
    }
}

The “jsdiv.js” file:


window.com_mypackage_mycomponent_JSDiv = function() {
	var mycomponent = this.getElement();
    
    
    // Handle changes from the server-side
    this.onStateChange = function() {       
    	label = document.createElement('label');
    	label.innerHTML = (this.getState().value);
    	mycomponent.appendChild(label);    	
    };       
}

Last the “jsdiv.css” file:


.myelement {
	background-image:url('img/helpme.png');
}

The image “img/helpme.png” is relative to the location of both css and js file (at the same level of the server side component).
So I have in the same package JSDiv.java, jsdiv.css and jsdiv.js and img folder with inside “helpme.png”.

In debugger window of chrome I get the error
GET http://localhost:8081/mycontext/APP/PUBLISHED/img/helpme.png 404 (Not Found)

css and js files are loaded correctly but not images.
I can’t change the css file: what can I do to retrieve correctly the image ?
Can i “redirect” the context to the “theme” context of images ? In this way I could copy the images in theme folder and images are resolved correctly. Unfortunately I can’t change css/js file.

In vaadin6 I was overriding a method of vaadin servlet to write my own header in html file but now it seems it is no more possible. We are using vaadin 7.0.4.

Thanks for any help,
Emanuele

Hi Emanuele,

I have the same problem as you. I have a .css that is included correctly through the @stylesheet in my code. The problem is that the images that the .css is referring to are not loaded in the browser. It tried to access
8i]


http://localhost:9090/testGWTOpenlayers/APP/PUBLISHED/public/img/xxx.png

But I have a 404 message from server.

I have also seen that jetty server in eclipse is throwing another error:


Rejecting published file request for file that has not been published: public/img/xxx.png

I have all static resources under public folder and I tried to copy it everywhere:

WEB-INF/lib/
WEB-INF/
build
VAADIN
VAADIN/WidgetSets

And with no success.

I’m using eclipse-juno and vaadin plug-in for eclipse. The server is jetty and I use it with jettyrun plugin.

Any help? Thank you!

Sergio

Hi Sergio,

I solved putting images in the @Javascript stereotype


@JavaScript({ 
    "myimage.png",  // if an image is used by css this is the way to resolve them
...

it is not so straightforward but it works for me.

Regards

Hi Emanuele,

Thank you! it worked!. The problem is that it is necessary to add the images one by one. Unfortunately it is not possible to add wildcards such as “img/*”

Thanks

I have used a “hybrid solution” that has worked for me: Include the stylesheet and needed images, fonts etc., in the old-fashioned widgetset way, and only include the JavaScript files or stylesheets with no external dependencies with the annotations.

For example you could have a folder structure like example, example/public, example/scripts. Then you would copy your css-file and all its related resources to example/public, create a widgetset-file like ExampleWidgetset.gwt.xml, copy content to it from some base-widgetset-file, and add line (this would try to find a file example/public/example.css).

Everything from the public-folder will be included in your widgetset (that is why I introduced the scripts-folder to avoid publishing scripts twice) and relative paths from your css-file will be correct. Downside of this method is, that it requires a recompilation of your widgetset. Also if you ended up having two widgetset-files (not required), you must also add to your main widgetset, and select main-widgetset when recompiling your widgetset.

You can still use the more lightweight and much faster to develop @JavaScript-method for your js-files as long as they do not need to include external files.

Thanks Riko for your suggestion.
Are you using vaadin6 or vaadin7 ?

Because my component is an extension of AbstractJavascriptComponent (vaadin7) and it is not a gwt component.

I’m looking for alternatives to @Javascript(myimage) because the browser tries to interpreting the image as javascript and gives error.

Anyway thanks

Hi Emanuele,

I faced the same problem with Vaadin 7 and I suppose it to be a bug, because you can not map “/APP/PUBLISHED/” in the web.xml having a theme set up for your application.

I decided to go the workaround to load css dynamically in the JS code from the location of my theme.


//Loads any css to the header to be used.
function loadCssFile(filename) {
	var fileref = document.createElement("link");
	fileref.setAttribute("rel", "stylesheet");
	fileref.setAttribute("type", "text/css");
	fileref.setAttribute("href", filename);
	document.getElementsByTagName("head")[0]
.appendChild(fileref);
};

loadCssFile("./VAADIN/themes/<your theme>/css/<your css>.css");

//VAADIN integration
com_test_<YourComponent> = function() {

	this.onStateChange = function() {
	//Your JS code
	}
}

Sorry to bother again with this problem but using an AbstractJavaScriptComponent it seems not possible to resolve images from a javascript file.

My component uses a javascript file that is added using @Javascript annotation. From this javascript file it is created an img element and attached to a div.
This img element has a src file with an image that I tried to add using the @Javascript but it does not work.

When I had a similar problem with an image loaded by a css file I added it to a @Javascript file and even if it is not a “clean” solution it worked; but a similar solution seems not work with an image loaded by javascript file.

Is there anyone who have/had a similar problem ?

thanks

You can use urls which are relative to the VAADIN folder of your application

@JavaScript(value = {"vaadin://addons/js/jquery-1.10.2.js")
public class MyAddon extends AbstractJavaScriptComponent{
}

The jquery-1.10.2.js library should be placed under VAADIN/addons/js

This will also work for css-files.