According to the JSF 2.0 specification, there are three ways to use h:graphicImage depending on the way by which JSF generates the "src" attribute of the HTML tag:
<h:graphicImage value="#{resource['images:next.gif']}"/>
<h:graphicImage library="images" name="next.gif"/>
<h:graphicImage url="/resources/images/next.gif"/>
The specification states that the first two should render exactly the same markup. In my JSF implementation (MyFaces 2.0.2), here is the output HTML that is generated:
<img src="/AppName/faces/javax.faces.resource/next.gif?ln=images">
<img src="/AppName/faces/javax.faces.resource/next.gif?ln=images">
<img src="/AppName/resources/images/next.gif">
So it seems that if I use (name, library) or (value) attributes, the image is always going to be streamed to the client by JSF's servlet. If I use (url) attribute, I can give direct link to the resource with no servlet intervention.
For me, the second approach - direct server URL to resource, is faster.
In what cases the first approach - specifying (name, library) or (value) attributes, be used?
For me, the second approach - direct server URL to resource, is faster.
The difference should be totally negligible. The "direct server URL to resource" approach also uses a servlet (the default servlet which is provided by the container). Please show your benchmark results.
In what cases the first approach - specifying (name, library) or (value) attributes, be used?
It allows you for serving the resources from within a JAR file. It also allows you for a nicer way of dynamically switching the library in the following manner:
<h:graphicImage library="#{user.prefs.looknfeel}" name="next.gif"/>
The library should actually point to a common resource library with all CSS/JS/images, not to a specific "images" library.
Related questions:
How to reference JSF image resource as CSS background image url
Changing JSF prefix to suffix mapping forces me to reapply the mapping on CSS background images
Related
In the SpringMVC documentation I see this for AbstractView:
Direct Known Subclasses:
AbstractExcelView, AbstractFeedView,
AbstractJackson2View, AbstractJExcelView,
AbstractPdfView, AbstractUrlBasedView,
AbstractXlsView, MarshallingView
Which implementation handles regular JSP Views?
The reason for my question is that I want to extend SpringMVC's JSP View, to support a Read-Only mode for a form. The regular view would be the normal JSP, but a Read-Only View would be an extension of the JSP where all fields are converted to labels, i.e. they can't be modified.
Any advice on this approach appreciated.
What I understand is you need to get a JSF component root, iterate over all elements, find input fields and replace them with non-input - labels instead?
JSP does not 'like' modifying it's components at runtime. In JSF I could suggest you implement a TagHandler to modify the component tree based on some parameter returned in the View Model.
In your case - a simple solution would be to either disable inputs based on parameter value
<h:inputText value="${inputValue}" disabled="${formDisabled}" />
or render different inputs based on parameter value
<c:if test="${formDisabled}">
<div><h:outputText value="${inputValue}" />
</c:if>
<c:if test="${!formDisabled}">
<h:inputText value="${inputValue}" />
</c:if>
I'd like to adapt my CKEditor so that when editing an image or other object it will show something like this in the editor view
<figure style="float: left">
<img src="sample.jpg" />
<figcaption>Caption</figcaption>
</figure>
On save it should transform this part to something else, for example
<node id=3 />
Does the CKEditor have any support for this, maybe through Widget, dataProcessor, or otherwise?
The short answer - yes, this can be done using the CKEDITOR.dataProcessor.
First thing to notice is that if you would use the widgets system (you will be interested in the image2 plugin), then you would be able to use downcasting to transform captioned images into whatever you want. Similar thing is done in Drupal 8, because Drupal saves captioned images as <img src=".." data-caption=".." ..>. (Note: Drupal 8 uses the image2 plugin but it overrides some things like e.g. downcasting method.)
The relation between mentioned CKEDITOR.dataProcessor and the widgets system is that the widget system uses the data processor to perform upcasting and downcasting of the widgets. Upcasting means discovering elements that should be turn into widgets and performing necessary transformations on the loaded data. Downcasting is the opposite.
You can also use the data processor without using widgets. You can do that:
either by using the filter.addRules() method on the editor.dataProcessor.htmlFilter and editor.dataProcessor.dataFilter filters,
or by hooking into the data processing on higher level using the editor.toDataFormat and editor.toHtml events.
I am using RichFaces 4. I am using flot as a JQuery Charting library and i want to implement a chart, that keeps refreshing itself via AJAX.
I get the data for the chart via JSON from my backing bean.
I am lost on how to get new data from a backing bean into a javascript variable. From what i understand i can't use <f:ajax> since there is no user interaction and no use of html input elements.
I think the solution would be the use of jsf.ajax.request. But i don't understand how to call that without an input-element either.
Following is a code snipped of how it should look like, but i don't know how to get the value from my backing bean into a javascript variable.
$(function() {
function update(){
//**dont know how this call should look like**
jsf.ajax.request('dev-form-input1', {render:'dev-form-output1'});
//'newAjaxData' would be the value from #{someBean.chartData}
plot.setData(newAjaxData);
// draw the chart with the new data
plot.draw();
//get an update every second
setTimeout(update, 1000);
}
I managed to send AJAX requests with jsf.ajax.request when using some input-element, but i didnt get the new value to render. And even if i could i wouldnt know hot to get it in a javascript variable (i dont have a lot of experience with javascript).
<h:form id="dev-form">
<h:inputText id="input1" value="#{someBean.chartData}"/>
<h:outputText id="output1" value="#{someBean.chartData}" />
</h:form>
note: i changed the javax.faces.SEPARATOR_CHAR to "-", because i need ":" for jquery.
Thanks for your help!
JSF is the wrong tool for the job. Use a webservice framework like JAX-RS, not a MVC framework like JSF. Then you can in the client end just use jQuery the usual way and so on.
See also:
Jersey (JAX-RS reference implementation) tutorial
Servlet vs RESTful
I have adapted a Pie chart JS object to use with JSF; in order to do so, I've created a custom component that outputs the appropriate markup and JS calls on the page, rendering the graph correctly. For reference's sake, this is the link for the tutorial I've followed for the JS part.
The next step is listening to clicks on the slices, and calling an action from a backing bean. The JS object for the chart already contains a placeholder function that listens to such clicks, so I believe the JS part of it is good. However, the JSF side bugs me still; I've read the Java EE tutorial, Jim Driscoll's blog posts, and all over the internet, and still can't get my head around it.
So, could anyone be so kind as to give a little example, of how I could bind a JS function call to an event listener in JSF, so that my backing bean would be nicely informed of which slice index had been clicked by the user?
It would be something close to:
function myChartObject() {
function onSliceClick() {
// This will somehow trigger JSF ajax event listener with slice data
}
}
class MyCustomChart extends UIComponentBase implements ClientBehaviorHolder {
// Is the decode() method the place to bind JS calls to JSF actions?
}
The closest I've found to my problem is something like this. However, I'd like to have this support in my own component, using the standard JSF API. Something perhaps close to this?
Thank you all in advance!
The JSF Javascript API to do AJAX calls is itself standardized (resource library "javax.faces", resource name "jsf.js") but adding full AJAX support in your own Java based custom component is a little elaborate.
The quickest way I can think of is following the blog by Jim Driscoll that you cited, and re-use the existing AJAX machinery offered by the <f:ajax> tag by wrapping your own Java based custom component in a composite component.
In Jim's example, I guess the following code from line 22 in his example is what you should render inside your onSliceClick function:
String click = behaviors.get("click").get(0).getScript(behaviorContext);
It would then look a little like this:
<ui:component
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:cu="http://javaserverfaces.dev.java.net/demo/custom-taglib"
>
<cc:interface shortDescription="Some Description">
<cc:attribute name="render" required="false" />
<cc:attribute name="clickAction" method-signature="java.lang.Object action" required="true" shortDescription="The click action method" />
</cc:interface>
<cc:implementation>
<cu:custom id="customId">
<f:ajax render="#{cc.attrs.render}" listener="#{cc.attrs.clickAction}"/>
</cu:custom>
</cc:implementation>
</ui:component>
Note that I haven't tested this, but it's the general idea. Of course it's also possible to do all of it directly in Java code but that surely takes some more work.
It looks like you want the ability to encode ajax style behaviors in your java compiled code, while integrating this with a J2ee stack.
The framework that comes to mind is JBOSS's Seam
Seam integrates directly with JSF by design, (GWT is more of a lightweight, standalone, statefull web-application framework - it doesn't have a lot of embedded features for direct integration with JMS and other modern J2ee features)...
Seam directly supports GWT-style ajax enabled components.
There is a good tutorial here : http://www.ibm.com/developerworks/java/library/j-seam3/
I have a question about the idea behind the fact, that only UIForm got the attribute prependId. Why is the attribute not specified in the NamingContainer interface? You will now probably say that's because of backward compability but I would preferre breaking the compability and let users which implement that interface, also implement methods for the prependId thing.
The main problem from my perspective about the prependId in the UIForm component is, that it will break findComponent()
I would expect that if I use prependId, then the NamingContainer behaviour would change, not only related to rendering but also when wanting to search for components in the component tree.
Here a simple example:
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
Now when i want to get the panelGroup component I would expect to pass the string "group" to the method findComponent(), but it won't find anything, I have to use "test:group" instead.
The concrete problem with that is, when using ajax with prependId="false". The ajax tag expects in the attributes update and process, that the values care of naming containers. It's a bit strange that when I use prependId="false" that I have to specify the full id or path, but okay.
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
<h:form id="test1" prependId="false">
<h:commandButton value="go">
<f:ajax render="test:group"/>
</h:commandButton>
</h:form>
Well this code will render without problems but it won't update the panelGroup because it cannot find it. The PartialViewContext will contain only the id "group" as element of the renderIds. I don't know if this is expected, probably it is but I don't know the code. Now we come to the point where the method findComponent() can not find the component because the expression passed as parameter is "group" where the method would expect "test:group" to find the component.
One solution is to write your own findComponent() which is the way I chose to deal with this problem. In this method i handle a component which is a NamingContainer and has the property prependId set to false like a normal UIComponent. I will have to do that for every UIComponent which offers a prependId attribute and that is bad. Reflection will help to get around the static definition of types but it's still not a really clean solution.
The other way would be introducing the prependId attribute in the NamingContainer interface and change the behaviour of findComponent() to work like described above.
The last proposed solution would be changing the behaviour of the ajax tag to pass the whole id, but this would only solve the ajax issue and not the programmatic issues behind the findComponent() implementation.
What do you think about that and why the hell is it implemented like that? I can't be the first having this problem, but I wasn't able to find related topics?!
Indeed, UIComponent#findComponent() as done by <f:ajax render> fails when using <h:form prependId="false">. This problem is known and is a "Won't fix": JSF spec issue 573.
In my humble opinion, they should never have added the prependId attribute to the UIForm during the JSF 1.2 ages. It was merely done to keep j_security_check users happy who would like to use a JSF form with JSF input components for that (j_security_check requires exact input field names j_username and j_password which couldn't be modified by configuration). But they didn't exactly realize that during JSF 1.2 another improvement was introduced which enables you to just keep using <form> for that instead of sticking to <h:form>. And then CSS/jQuery purists start abusing prependId="false" to avoid escaping the separator character : in their poorly chosen CSS selectors.
Just don't use prependId="false", ever.
For j_security_check, just use <form> or the new Servlet 3.0 HttpServletRequest#login(). See also Performing user authentication in Java EE / JSF using j_security_check.
For CSS selectors, in case you absolutely need an ID selector (and thus not a more reusable class selector), simply wrap the component of interest in a plain HTML <div> or <span>.
See also:
How to select JSF components using jQuery?
How to use JSF generated HTML element ID with colon ":" in CSS selectors?
By default, JSF generates unusable ids, which are incompatible with css part of web standards