Blog Archives

July 26th, 2011
10:31 am
Extra unwanted margin around an HTML textarea in Google Chrome

Posted under CSS
Tags , , , , , ,

Chrome places an unwanted 4px bottom margin on a textarea, which is impossible to elminate purely by the margin settings.

In addition, the other browsers sometimes have related issues.

This post on StackOverflow discusses the issue, and the Chrome bug issue may be found here.

Issues like this can be caused in inline and inline-block elements, due to side effects of the line height/vertical alignment of textual elements. They can be hard issues to diagnose as the cause of the extra margin is not readily visible in tools like Firebug or Chrome’s developer tools/debugger. In order to see it, I added an extra div with a border around the element, and the margin was then clearly visible, but of course it was still not reported as a margin on the textarea element, which steadfastly maintained its story that no margin was present!

As per the StackOverflow article, there are 2 ways around this issue:-

  • If the textarea is set to have vertical-align:top then this eliminates the problem. It also has the advantage of maintaining the element as inline-block – in Chrome’s case this is the default, and with other browsers this will often be used in order to allow margins etc. which an inline element will not allow.
  • Another fix for the problem is to set the textarea to display:block, i.e. to make it a block element. This is fine, but it should be noted that as the element is not natively a block type element, IE7 and earlier IE versions will not handle this. IE8 and IE9 will allow an inline element to be redesignated as a block one. Therefore, the first method has better browser compatibility.

No Comments »

July 26th, 2011
10:05 am
Controlling textarea resizing in HTML

Posted under CSS
Tags , , ,

A number of web browsers (notably Firefox, Google Chrome and Apple Safari) have a feature whereby a textarea element in an HTML form can be dynamically resized after rendering, by allowing the user to drag the corner of the element. At the time of writing , IE and Opera do not have this feature.

This is often a desirable feature, but in order to preserve layout it is also desirable to restrict and control it as desired. The following facilities are available to do this:-

  • It can be disabled completely using the css property resize:none. Note that this is a CSS3 property, which limits its scope of use.
  • Another means to do this is by using the min-width, max-width, min-height, and max-height properties, which have the advantage that they are CSS2 properties and therefore more widely supported. They are also more flexible in that they allow precise control of the amount of resizing allowed on the element. Resizing can be disabled completely by setting the minimum and maximum width/height to the actual width/height values.

No Comments »

July 25th, 2011
11:35 am
Using the Primefaces p:panel component

Posted under JSF
Tags , , , ,

This post details some tips discovered whilst experimenting with p:panel.

1/ The toggle button on the right hand side of the panel is rendered with ui-state-default. This does not look attractive with some themes – it often looks like a bit of a zit due to the background on the thick plus sign icon. I noticed that the dialog component p:dialog does not render its close icon in the header with ui-state-default,  and this looks much more attractive as the surrounding highlight on the icon only shows on hover.

This can be applied to p:panel by removing the ui-state-default class from the anchor tags around the icons on the panel header. The following example jQuery performs this (in my case, the panelDivId argument is the ID of an h:paneGroup/div surrounding the panel:-

function ss_PanelFixIcons(panelDivId) {
    var escapedPanelDivId = panelDivId.replace(/:/g, ‘\\3A ‘);
    var panelIcons = jQuery(‘div#’ + escapedPanelDivId + ‘ div.ui-panel-titlebar > a.ui-panel-titlebar-icon’);
    panelIcons.removeClass(‘ui-state-default’);
}

 

2/ It would be nice to be able to explicitly expand and collapse the panel as well as to just toggle it. In fact the panel widget does expose its current state via its cfg property, although this is not publicly documented. The following example functions use this to provide explict expand, collapse, and set to passed boolean state functions. In addition a function is provided to get the current panel state:-

function ss_PanelExpand(widgetVar) {
    if (widgetVar.cfg.collapsed) {
        widgetVar.toggle();
    }
}

function ss_PanelCollapse(widgetVar) {
    if (!widgetVar.cfg.collapsed) {
        widgetVar.toggle();
    }
}

function ss_PanelSetCollapsed(widgetVar, state) {
    if (!widgetVar.cfg.collapsed == state) {
        widgetVar.toggle();
    }   
}

function ss_PanelGetCollapsed(widgetVar) {
    return widgetVar.cfg.collapsed;
}

 

3/ A query came up on the Primefaces forum on how to lazy load the panel, as it eagerly loads and the expand/collapse is all done client side. The post is available here. the solution is straightforward:-

  • Use a toggleListener to update a renderPanel property to true if the panel state from the event was visible, and false if it was hidden.
  • Then conditionally render a content h:panelGroup inside the panel, using the above property as the rendered property.
  • One issue with this is that the actual panel toggle occurs before the ajax update of the panel not after, so with the slide toggle effect on (say with toggleSpeed=”1000”), you see an empty sliding toggle first, then a non sliding ajax update. In this case it is best to turn off the slide effect with toggleSpeed=”0”. If you use another button to toggle the panel you can get around this, as the onComplete event for the button can toggle the panel (via its widget/ as per the above JavaScript), and this happens after the Ajax to render the panel. In practice you would have to somehow overlay the standard toggle button with another one of your own, or manually disable the standard one via CSS, as if you set toggleable=”false” for the panel this completely disables toggling via the widget as well as removing the toggle button.
  • It is probably not worth the trouble of trying to get sliding to work if you are lazy loading. Note that when I tried some older/slow machines the slide effect rendered poorly anyway, so this should also be born in mind.

No Comments »

July 21st, 2011
10:58 am
More useful Posts about inline-block and alignment

Posted under CSS
Tags , , , , ,

Update 18/1/2012

I was having trouble getting cross theme and cross browser consistency in aligning text adjacent to an icon in a series of IconTextButtons of mine, inside a toolbar.

Both the icon and the text were in spans set to display:inline-block and the spans were inside a div. I found the following useful in solving the issue :-

  1. The key issue turned out to be that the line-height was very different across Primefaces themes. The font size was constant at about (effectively) 11.5px, but the effective line-height varied with the them between 12px and 16px. This was the main cause of the issue in getting good alignment.
  2. I just set a fixed line-height of 14px for all the buttons in the toolbar, and this solved the cross theme (and cross browser) issues.
  3. The text was to the right of the icon, and found that tweaking the top margin for the icon set the position of both it and the text vertically, due to the adjacency-relative way in which vertical-align works.
  4. In order to adjust the vertical alignment of the text slightly relative to the icon, I found that setting a small bottom margin on the text achieved this, so one to bear in mind when experimenting.
  5. I had also tried padding changes as well as margin, but the effects (or lack of them) were similar to tweaking the margins.

 

Original Post

This post gives a good description of the effect on margins and padding for inline vs. block elements elements.

This StackOverflow post point out the effect of adjacent inline elements on the vertical alignment of an element – in this case an element was pushed down a few pixels due to the prescence of adjacent inline elements.

I was trying to align text and buttons in a narrow vertical toolbar, and as I have found previously, different browsers render differently.

The best consistency across browsers was obtained as follows :-

  1. Use display:inline-block to allow vertical margins to be obeyed on the elements. They can then be precisely adjusted (but may still behave differently depending on the adjacent elements). inline-block has decent cross browser support. IE6 and IE7 only support it on elements with a native type of ‘inline’ – see this post for cross browser support details.
  2. Using vertical-align:bottom seems to give the best cross browser consistency.
  3. Top and/or bottom margins generally need to be tweaked for each individual case depending on element adjacency. (Depending on the case you may need to set a top or a bottom margin to have the desired effect consistently across browsers.) For example, I had to treat a text only span differently to a text span adjacent to a couple of buttons on the bar.

No Comments »

July 19th, 2011
10:14 pm
Accessing JSF Resource Bundles from Java Code

Posted under JSF
Tags , , ,

This is useful to be able to do. Typically you will want to declare a resource bundle in faces-config.xml to load it once for the application. You then refer to it from any JSF page that needs it.

However, you often want to also load messages from code. An example might be the generation of custom faces messages or other error messages generated by the code.

It is clearly therefore desirable to access the same message bundle that JSF has loaded, so that it is specified centrally, loaded once for the application, and reused by both JSF and Java.

This post here by Andy Gibson details how to do this. The code fragments are shown below, in case the link ever becomes broken:-

 

Resource File

firstName=First Name
lastName=Last Name
forgotPassword=Forgot Password?
usernameTaken={0} is already taken

 

faces-config.xml

<application>
    <resource-bundle>
        <base-name>org.fluttercode.resourcedemo.MessageResources</base-name>
        <var>msgs</var>
    </resource-bundle>
</application>

 

Class MessageProvider

public class MessageProvider {

    private ResourceBundle bundle;

    public ResourceBundle getBundle() {
        if (bundle == null) {
            FacesContext context = FacesContext.getCurrentInstance();
            bundle = context.getApplication().getResourceBundle(context, “msgs”);
        }
        return bundle;
    }

    public String getValue(String key) {

        String result = null;
        try {
            result = getBundle().getString(key);
        } catch (MissingResourceException e) {
            result = “???” + key + “??? not found”;
        }
        return result;
    }

}

Backing Bean

@Named
@RequestScoped
public class SomeBean {

    public String getMessage() {
        String msg = new MessageProvider().getValue(“someMessage”);
        return MessageFormat.format(msg, “SomeValue”);
    }
}

Example Code to generate a custom FacesMessage (from CoreJSF Edition 3, Page 332)

public void validateDate(ComponentSystemEvent event) {
    UIComponent source = event.getComponent();
    UIInput dayInput = (UIInput) source.findComponent(“day”);
    UIInput monthInput = (UIInput) source.findComponent(“month”);
    UIInput yearInput = (UIInput) source.findComponent(“year”);
    int d = ((Integer) dayInput.getLocalValue()).intValue();
    int m = ((Integer) monthInput.getLocalValue()).intValue();
    int y = ((Integer) yearInput.getLocalValue()).intValue();

    if (!isValidDate(d, m, y)) {
       FacesMessage message = com.corejsf.util.Messages.getMessage(
            “com.corejsf.messages”, “invalidDate”, null);
        message.setSeverity(FacesMessage.SEVERITY_ERROR);
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(source.getClientId(), message);
       context.renderResponse();
    }

}

No Comments »

July 19th, 2011
8:54 pm
JPA – Accessing the primary key ID allocated during a persist operation on a new entity

Posted under JPA
Tags , , , ,

I wanted to do this in order to use the ID as part of the creation of a Base64 encoded tree path in another column in the same row, as I was using path enumeration as my tree algorithm (see here on slideshare.net for an excellent article on database tree algorithms).

The simple answer is – you can’t do this reliably, unless you allocate IDs yourself in some way.

  1. The ID is not available before a persist. I could call flush and then read it back, create the TreePath and then persist again – this is safe. This is discussed here on Stack Overflow.
  2. The JPA Lifecycle callback @PrePersist does not guarantee that the ID is visible. The net is rather quiet on this but this post here about hibernate says it cannot be relied upon  (@PostPersist would of course be different). There are strong limits on what you can do in such a callback or entity listener. For example, you can’t do entity manager operations, persist entities, or refer to other entities etc.
  3. Triggers would be another way to avoid the double update. I could set the rest of my TreePath prior to the first persist, and then retrieve the actual ID in a before insert trigger using the new.TreePathID syntax (MySQL and Oracle use similar syntax in this respect). I could then encode it in Base64 using a stored procedure, and append it to the treepath. Oracle has a built in package with Base64 encoding and decoding available (the utl_encode package). For MySql there is an open source example on the internet here. From posts on the net, e.g. here, triggers do work in MySQL via JPA.

The best solution looks like using triggers on the database server, as this avoids the double update. I have yet to investigate/try this.

No Comments »

July 19th, 2011
5:35 pm
Calling a utility POJO from a Session Bean

Posted under EJB
Tags , , , ,

Update 17/10/2013

This StackOverflow Post here is by David Blevins, EJB 3.1 expert group member among many other things. It confirms my original post below that plain CDI beans can be freely mixed with EJBs etc. and that you use what you need based on the features offered. It confirms that an @ApplicationScoped bean is pretty much an @Singleton but does not have the @Startup capability to run a method when the application starts. There is a javax.inject.Singleton as well as a javax.ejb.Singleton, however this post here points out that javax.inject.Singleton is not part of the official CDI spec. Therefore, it suggests (as does David Blevins in the above post) that you use @ApplicationScoped if you don’t need the special transactional/locking features of @Singleton (javax.ejb.Singleton that is), as it can be a lot faster.

In my case, there are a number of places where I may now end up replacing intermediate @Stateless beans with @Application scoped ones for simplicity and performance.

Original Post

A number of blog posts on this maintain that you need to create an EJB singleton for this, and set it to readonly, perhaps with Transactionattribute  set to unsupported to suspend the transaction whilst in the utility POJO/EJB.

Assuming the utility POJO did no database access and had no transaction involvement, I could see no reason for this. After all, an EJB can create and use an ArrayList for example without having to take any special actions. Why should my utility POJO be any different? In my case, the POJO was using the Apache Base64 encoder to encode an ID in Base64. When I subsequently read the CDI spec for info on this, it came to the rescue. CDI states that you can pretty much inject anything into anything else.

In particular, on P13 of the weld spec, Section 2.2.2 “SessionBeans” it states :-

“You can inject one session bean into another session bean, a managed bean into a session bean, a session bean into a managed bean, have a managed bean observe an event raised by a sessionbean, and so on.”

Therefore, if I just have a plain utility class which has nothing to do with session beans, the DB, or transactions, I can just inject it with CDI and call it from a session bean. I do not have to make it a singleton session bean/with readonly locking/transactions not supported etc.

The restriction would be that unlike session beans it could not be called remotely with all the clever EJB remote stuff, however this is absolutely not required in cases like this, I would just deploy it as a utility library in the local container along with the rest of the application. Each application server would therefore have its own copy.

This finally makes sense. In my case, it also works perfectly well when I inject an application scoped POJO into a stateless session bean.

No Comments »

July 7th, 2011
9:52 am
A ui:param/attribute value is passed on invisibly to a called custom tag with attribute of the same name

Posted under JSF
Tags , , , ,

I passed a styleClass attribute to a facelets decorator using <ui:param>. The decorator in turn used a custom tag which had a styleClass attribute.
I discovered whilst looking in Firebug that the styleClass attribute passed to the decorator was being passed on to the custom tag, even though I had not specified a styleClass attribute on the custom tag. The CSS class name was clearly visible in Firebug.

I’ve investigated this with a test application and have confirmed the following points. I have also logged these points under a Mantis issue here.

Note that this was running on Mojarra 2.0.4 FCS, and I am not clear whether all of these issues are by design or would be considered a bug, and how consistent they are across other versions/JSF implementations:-

  1. A ui:param passed say to a decorator is indeed visible via EL in a custom tag called from the decorator. If the custom tag has an attribute of the same name, this will be passed to the tag in preference, but crucially, if the attribute is omitted/defaulted on the tag, the tag will then see the ui:param from the calling decorator.
  2. The above issue in 1/ even occurs if the above decorator is changed to be itself a custom tag, and the ui:param instead becomes an attribute of the parent/calling custom tag. In this case, the nested custom tag sees attributes passed to its parent if the same attribute is not explicitly passed to it.
  3. Fortunately, if a child custom tag is called with an explicit attribute with the same name as an attribute or ui:param passed to its calling tag or decorator, the value in the calling tag/decorator is not modified. This means that you can call child tags without corrupting state in the calling environment.
  4. Point 3/ is also true when a decorator is called with ui:param. If the ui:param has the same name as one used in the caller (either defined there or passed to it), changing the value of the ui:param within the ui:decorate tag to pass it to the decorator does not change the value of the same named parameter outside of the ui:decorate tag.
  5. If a child decorator modifies a ui:param passed by its caller, the modified value is visible only within the child decorator. On return to the calling environment, the ui:param value reverts to what was passed to the child by the caller. This indicates that there is scoping going on.

 

The lessons from this are therefore as follows:-

  1. The prime gotcha here is that if you omit an attribute on a custom tag call or a ui:param on a decorator call, a ui:param or attribute value in the caller’s environment will be visible to the called environment exactly as if it was passed in explicitly! You must therefore take great care to ensure that child calls have explicit empty/null attributes or ui:params specified where there is a name clash with one in the calling environment.
  2. Attribute values and ui:param values are scoped, and you can safely pass the same named ones with different values to child decorators or custom tags without affecting the values in the calling environment. This is even true when defining a ui:param within a ui:decorate tag – it does not affect the value of a similarly named ui:param outside the ui:decorate tag.
  3. Changing the value of a ui:param in a child decorator/tag does not change the value of the same named one in the calling environment. It does however cause the value to change after the point of change in the child environment.

No Comments »

July 6th, 2011
5:27 pm
Facelets – using <f:subview> to create a naming container

Posted under JSF
Tags , , ,

<f:subview> creates a naming container and so may be used to avoid ID collisions on a facelets page. It says in CoreJSF, 3rd edition, that this is not needed for facelets, but as it turns out, I have found a significant use for this.

One of my custom tags is a complex multi table tree browser component, which has lots of optionally included/defined markup. It therefore needs to be a custom tag rather than a composite component, as the latter would not give the required flexibility.

The issue I hit with this is that I use multiple variants of this tree browser on the same page, to browser different tree structured data within my application. The trees are all polymorphic, and indeed share and subclass the same base JSF controller class, as well as re-using the same base custom tag. As there is more than one on a page, I have potential ID collisions, and so to avoid this, using <f:subview> to define a naming container in the custom tag is ideal in this case.

This is helped by the fact that in JSF 2 you can actually pass an ID to a custom tag and define it in the tag in <f:subview> using an EL expression. Whilst this is normally unorthodox and not encouraged, in this case it makes perfect sense – the value does not come from a bean, but is a constant string passed via the attribute.

No Comments »

July 6th, 2011
5:16 pm
Facelets–using a custom tag interchangeably instead of a Decorator

Posted under JSF
Tags , , ,

Update 26/7/2011

Some more points that were omitted or incorrect in the first posting:-

  • A handy feature with templates/custom tags is that you can render children of the template/tag at the call site simply by using a <ui:insert> without a name. You therefore do not need to use a <ui:define> tag in this case, and all children which are not contained in other <ui:define> or <ui:param> tags will be rendered as part of this default <ui:insert>
  • The statement below that it is not possibly to insert a number of different markup variants in a composite component is incorrect. A composite component can have a number of named facets just like a ‘real’ JSF component, and these allow markup to be inserted in the same way as <ui:insert>/<ui:define> does for a template or custom tag.

Original Post

I had a complex decorator which was used for tree browsing. It had a number of ui:inserts for custom markup, plus also a large number of <ui:params> to define EL parameters used within it.

This all worked fine, and even looked quite tidy as all the <ui:params> were listed one per line below each other. However, it was all rather verbose compared to using a custom tag where you would use attributes instead to pass the EL parameters.

It turns out that you can convert a decorator to be a custom tag with no effort as they operate similarly. You merely need to register the xhtml file in a taglib as with any custom tag, and you can then call exactly the same code as a custom tag instead of a decorator.

The neat tricks here are that:-

  • <ui:params> become attributes which are less verbose, but the tag itself does not know any difference and needs no changes.
  • <ui:insert>/<ui:define> work perfectly with a custom tag exactly as they do with a decorator.

 

Another nice point on this is you can develop custom tags that include pseudo ‘child markup’ in similar fashion to composite components, by using the <ui:define>s. Providing you do not need the other features of composite components such as retargeting, Ajax etc., custom tags can be very useful where you have a need to insert a number of different markup variants for different flavours of the tag, as you cannot do this so flexibly with a composite component.

The technique of using <ui:inserts> in a custom tag is hinted at somewhat obliquely in Core Javaserver Faces, 3rd Edition, on P196 in the listing of the planet custom tag, which contains a <ui:insert> called content1.

No Comments »