Two Laptop Bag*
The moose likes JSF and the fly likes Change CSS from ControllBean Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » JSF
Bookmark "Change CSS from ControllBean" Watch "Change CSS from ControllBean" New topic
Author

Change CSS from ControllBean

Johan Rignas
Ranch Hand

Joined: Jul 17, 2011
Posts: 30
Hi. Any idea how to change the CSS of given component id's in a ControllBean?
Johan Rignas
Ranch Hand

Joined: Jul 17, 2011
Posts: 30
What I would like to do is to change a background image for a special event happening. If I cant change the CSS in my bean, maybe I can call a javascript method from the bean?
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16103
    
  21

First of all, JSF Backing Beans are not Controllers. They are Models. Action methods are not part of the MVC architecture, they're the interface between the Model and the Business Logic, not the Model and the View (which is what a Controller is). You very rarely write any Controller code in JSF. The Controllers were pre-written and live in the FacesServlet and in the tag renderers.

CSS can come from:

1. A static CSS file
2. A CSS file dynamically generated by a servlet or JSP
3. Inline CSS stomped into the View definition by brute force (this can be very ugly)
4. CSS element supplied via the styleClass or style attributes on a JSF HTML element.

You can "change CSS" by using option 2, by doing unmentionable things of various types for option 3, or by supplying CSS information generated by backing beans and referenced via EL expressions in option 4.


Customer surveys are for companies who didn't pay proper attention to begin with.
Johan Rignas
Ranch Hand

Joined: Jul 17, 2011
Posts: 30
Thanks for reply. I have learned to always follow the MVC for the beans which makes the action methods connects to the "C". Will try to put how it works in mind...
Lets try to solve the question. Is it possible to retrieve a HtmlPanelGroup?



If it´s not possible I can take it one step further and create the PanelGroup in the bean and refer to it?


Any tips?
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16103
    
  21

MVC is always treated as though it ran in isolation. If that was true in the Real World, all you'd have would be a Model and a View updating each other and getting nowhere. In reality, you have to jump off at some point and connect to the rest of the application. That's what the actions do. There probably ought to be a name for that aspect, but if anyone ever invented one, I don't know it.

Anytime you start meddling with JSF internals, the first question should be "Is this necessary"? JSF is designed to work almost entirely with POJOS, with the notable exception of its datamodel classes, and even they are passive objects.

Instead of doing bindings and mucking around with the FacesContext, try this simpler solution:



In the backing bean (myBean):


Define the specialStyle and normalStyle CSS classes in your CSS in the usual way.
Johan Rignas
Ranch Hand

Joined: Jul 17, 2011
Posts: 30
Very nice and clean solution! But the problem for me is that I need to go for the components id. This because I have a list of panelGroups with different id´s but same styleClass... Just changing the style are affecting all panelGroups and not the specific one.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16103
    
  21

I'm not sure what that really meant, but there's absolutely no reason why every panelGroup has to get its style information from the same property. You can have as many styleClass-returning properties in a backing bean as you want.

As a general rule, you DON'T want the backing bean (Model) to know IDs or other specific properties of the View. It's a violation of MVC's fundamental premise. Among other things, it makes it more likely that changes to one will force changes to be made to the other. An ideal Model can be shared between many different types of Views at the same time. For example, a Chart view, a PDF view, and several different "skins" on a web View. If the Model is tied to one specific View or View architecture, you lose a lot.

Although you can employ a different backing bean property to return a different class for each panelGrid or panelGroup, that's not the only way that you can manage things. You can also define ID+class CSS selectors, cascading style classes, and all the usual CSS tricks as well. I do this fairly frequently.
Johan Rignas
Ranch Hand

Joined: Jul 17, 2011
Posts: 30
Ok. I try to illustrate what I would like to do:


Problem here is clearly that the styleClass is not even connected to the bean. And when I connect it to the bean:

Then all panelGroups get the same styleClass which is not desirable.

Cant see how to solve it with the loop and cant see how to make it look good without the loop...
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16103
    
  21

Don't use JSTL with JSF. That's just compounding your problems.

There are 2 ways to do this. For general layout, you can use the Facelets ui:repeat instead of c:forEach.

For structured (tabular) layout, the better way is to use a dataTable:


MyBean.groups is a table DataModel (javax.faces.DataModel) object that wraps a collection of table row objects (custom subclass of java.lang.Object) which are the items that you will present on each table row. If you define the table row object class to contain a "style" property in addition to whatever specific items you want to present for that particular "panelGroup", then it puts everything in one tidy place and you don't have to re-calculate unless you update the table DataModel.

I should mention that "panelGroup" is not a first-class display element. It's a child element for panelGrid that does the exact opposite of what "colspan" does for HTML TABLE columns. That is, it takes 2 (or more) elements that would normally occupy separate cells and puts them both in a single cell.
Johan Rignas
Ranch Hand

Joined: Jul 17, 2011
Posts: 30
As I can see it I would need to add "style" variable to all my objects in the list(DataModel) then, which in turn is Entities. Instead of having the "styleClass" refer to the "var" it somehow should refer to "myBean" to be able to change on special events. But yet again the problem is how to separate the different "column"s for the events. Only one specific column should be affected.
Example for simplicity: If you move the mouse over one of the columns it should be highlighted. (For my problem it is when a object is dragged. I have when the event happen and would just like to change css somehow. A good solution would just be to change css file but again: how to separate the columns?)
Johan Rignas
Ranch Hand

Joined: Jul 17, 2011
Posts: 30
It also seems like neither h:dataTable or ui:repeat supports hashMaps?
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16103
    
  21

Johan Rignas wrote:It also seems like neither h:dataTable or ui:repeat supports hashMaps?


Correct. They enumerate ordered collections. HashMaps are random-access and have no inherent order. You could argue ordering by keys, but others would protest that they want order by values.

Hashmaps are overkill here. Just stuff the CSS classname into a column of the dataModel and it will be there when you need it without the need for hashtables or gnarly EL.
 
GeeCON Prague 2014
 
subject: Change CSS from ControllBean