Friday, November 02, 2007

Changing appearances.

Lately I've been working on an application that can serve offices in different countries. So what I hear you say.........I do that every day.............use the 'locale.language', use a bundle and be happy ;-) Ok, I know that, but I want to have changing appearances, not only changing text. That can also be done by using a skin selector for instance like the one below:

<skin-family>#{facesContext.viewRoot.locale.language=='de' ? 'german' :
'english'}</skin-family>

You can use this in the same way as I did in one of my previous posts.

However, I want the application to behave in a way that not the whole look and feel changes, but that only some country specific elements automatically change. I will not go in to the details of the application, but I will try to explain the concept, based on license plates. Imagine a car rental company with cars and offices in different countries.

Whatever country (or even state for that matter) you are in, the license plates are different. Yellow with black numbers, white with red numbers and so on and so on.....

If you have an application in which you show license plates, you can do that by using a 'plain' outputtext field in a table column. This will show the license of the car as plain text.

For me that just doesn't 'feel' right. It would be much nicer if you could add some features that enable you to recognize the country by just looking at the licenseplate.


Wow........... I want that, how can I do that ?

There are several problems here. First one is that licenses have different colors for the background color, the text color and the borders. The dutch plate has a yellow background background-color:rgb(255,255,0);

and a belgian plate has red text color:Red;

You can achieve this by using the styleClass attribute.
<af:column sortable="false" headerText="License">
<af:inputText
id="myLicense"
rendered="true"
value="#{Car.license}"
styleClass="InputLicensePlateStyleNL"
inlineStyle="width:100px;"/>
</af:column>

You can define the style in a css like this;
.InputLicensePlateStyleNL
{

border:2px solid black;
background-color:rgb(255,255,0);
background-repeat:no-repeat;
font-weight:bold;
text-align: center;
color: black;
width:90pt;
height: 20pt;
padding-top: 10pt;
}
If you define all the necessary styles in a css, according to the standard of a country, the looks of the license plate should be recognizable.

A good reader should have noticed by now that something is missing. The styleClass InputLicensePlateStyleNL is only valid for one specific (the dutch) license. This is the second problem. If you want to have coutry specific look and feel, you need something extra.
styleClass="InputLicensePlateStyle#{Car.country}"

You can concatenate a String and EL expression. This will evaluate to a valid value.

Now you can try to take this one step further.
There are license plates that are not country specific, but state specific.


Maybe they even have their own specific background images.


If you really want, you might even try to add county and city to this expression.

styleClass="InputLicensePlateStyle#{Car.country}#{Car.state}"

In the case of this example you would have InputLicensePlateStyle concatenated with US and CA resulting in InputLicensePlateStyleUSCA. This is defined in the stylesheet.
This styleclass has the appropriate background image, and colors to render a Californian plate, and looks like this:
.InputLicensePlateStyleUSCA
{
background-image:url("../images/ca.jpg");
border:2px solid black;
background-color:rgb(255,255,255);
background-repeat:no-repeat;
font-weight:bold;
text-align: center;
color: black;
width:90pt;
height: 20pt;
padding-top: 10pt;
}


This post shows that you can style almost anything, as long as you 'have the looks'. Dynamically building the styleClass is a very powerful (and maybe even hidden ? ) feature. I will use it more often from now on.

Friday, October 12, 2007

Hibernate untill your ADF-faces Spring (part II)

If you are an ADF developer with an Oracle forms background, you've probably been using ADF Business Components to implement the business and integration layer of your webapplications. So have I. Hibernate was new to me, and I will try to explain just a little bit in this post. I have some very good developers in my team that do the hard work on the hibernate part of this project. I will keep it simple and just explain some of the basics.

The persistence layer contains a set of classes and components, which handle the tasks of persisting or retrieving objects to or from the underlying database. This layer includes a domain model that includes the business entities. Hibernate is a typical example for technologies used in this layer.

There is a thing to keep in mind. You don't write sql queries. The hibernate framework will generate those for you. This is called "Hibernate Query Language" (HQL). The generated Language is based on the tye of database that you are connecting to (database independent indeed !). As an Oracle developer you really have to get used to this (Why should you.... ? Just use Oracle 11g database;-)).

Ok, but how does it work ? Down here you see the content of the project:



You can see that there are three main packages:
A Dao package for the data access,
a Model package, containing the orm and the service
and a util package containing the DAOfactory and a HibernateUtil class.

How this all works together is very well explained in this document.

I'll just explain a (very) little bit on what the involved components will do for you:
Generic data access object (DAO)
The GenericHibernateDao class contains methods that are used by every DAO,
for instance the findAll and findByCriteria methods.

Entity Dao's
The specific entity Dao's extend the GenericHibernateDao and therefor inherit the generic methods. In this case the findByName method is specific for Employee and is implemented in the EmployeeDao.

Model Class
A Model Class for Employee which tells hibernate what table this is based on and that extends the OrmEmployees class. The OrmEmployees class holds the properties under Hibernate Control for Employee such as column mappings with the getters and setters.
package com.blogspot.lucbors.core.model;
.................
import com.blogspot.lucbors.core.model.orm.OrmEmployees;

@Entity
@Table(name = "EMP")
public class Employee extends OrmEmployees
{
/**
* Default Constructor.
*/
public Employee()
{
super();
}
...................

And
package com.blogspot.lucbors.core.model.orm;

imports here
......................
/**
* Class holds the properties under Hibernate Control for Employee.
*/
@MappedSuperclass
public abstract class OrmEmployees
{
@Id
@Column(name = "EMPNO", unique = true, nullable = false)
private Long id;
@Column(name = "ENAME", nullable = true)
private String firstName;
@Column(name = "JOB", nullable = false)
private String lastName;

/**
* Default Constructor.
*/
public OrmEmployees()
{
super();
}
/*......getters and setters go down here */
}

core-<app>.xml
The employeeServiceImpl is used to expose the functionallity. We mapped this in the core-empdemo.xml. This is a file that tells your application exactly where to get the service that you are using (contextConfigLocation). You should put this file on your classpath.

The hibernate configurationfile (hibernate.cfg) for indicating
the database version (duh) and the mapping of classes.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
...................
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<property name="hibernate.current_session_context_class">org.hibernate.context.ThreadLocalSessionContext</property>
.............
<mapping class="com.blogspot.lucbors.core.model.Employee" />
</session-factory>
</hibernate-configuration>

In the hibernate.properties file you can define the database connection:
#############################
# Hibernate Database Connection #
#############################

hibernate.connection.url=jdbc:oracle:thin:@localhost:1521:xe
hibernate.connection.username=hr
hibernate.connection.password=hr
hibernate.default_schema=hr

All this is something that you configure at the beginning of the project. Normally there will be one "hibernator" to do this configuration.

I'm curious if I ever get to write part III on "Hibernate untill your ADF-faces Spring", because as we speak, there are some issues in the project. Nothing to do with technology or architecture, it's (again) all about politics..........

Thursday, October 11, 2007

Hibernate untill your ADF-faces Spring (part I)

It's october and summer ended a couple of weeks ago. A lot of rodents and bears prepare for winter and hibernation. So will I! I got involved in a project in which creativity was pushed to the limit in a very early stage.

We wanted to do a project with ADF (full framework) for one of our customers. This approach wasn't allowed. I've been mailing and talking about this case with some people at oracle (Steve Muench a.o.) but it is at it is...Either you like it or you don't. There are customers who, for whatever good reason, don't want to use ADF. John Stegeman wrote a nice entry on his blog about the pro's and cons, and about 'pride and prejudice' concerning JDeveloper and ADF.

In this case however, instead of forbidding the use of any part of the ADF, my customer decided to allow a Poc (Proof of Concept) in which I (and my co-workers) were allowed to use the ADF-faces part of the framework.

The consequence was that we had to think of an alternative application architecture.
Because of customer standards we finally decided to develop a system that in the end will cover two layers: a GUI made up of ADF-faces and a backend made up with spring hibernate talking to an Oracle database. This is not something very special. In the end it is just java talking to java, and this should not be a problem, but we wanted to make sure that this approach worked, and we never tried before. In the company I currently work for, the Oracle Unit does JDeveloper-ADF projects and the Java Unit does everything except Oracle........I'm trying to bring those two together.

We did an internal pilot on the EMP table in the HR schema in the Oracle database.

In the next couple of posts on this blog I'll try to give you a step by step guide of this approach. You can see the draft architecture in the picture below, in which I also show you which post will cover which part of the solution.



Because this blog was created to talk mainly about ADF, I will tell you the most important part (ADF-faces) in this part of this series. So that if you don't want to know how hibernate works, you still know how to use it in your ADF-faces front end. Here is what you need: Have your J2EE developers create a jar-file with all the logic concerning the Business and Integration layer. (I talk about how you could make this layer in Part II.). For now lets asume it's all created for you.

Now, the first thin you have to do is to include this jar in your ADF-faces project. Next you create a backingbean that uses the EmployeeService to find all employees, create a Page with an ADF-table, bind this table to the backingbean, run the page, and it should work.

The backingbean
package com.blogspot.lucbors.view.backingbeans;

import java.util.List;
import javax.faces.context.FacesContext;
import com.blogspot.lucbors.core.model.service.EmployeeService;
import org.springframework.context.ApplicationContext;
import org.springframework.web.jsf.FacesContextUtils;

public final class FacingHibernateBackingBean {

private EmployeeService empServ;
private ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());

public FacingHibernateBackingBean() {
}

public EmployeeService getempServ() {
return empServ;
}

public void setempServ(EmployeeService empServ) {
this.empServ = empServ;
}

public List getAllEmployees() {
empServ = (EmployeeService)ctx.getBean("employeeService");
return this.empServ.getAllEmployees();
}
}



Getters and setters shouldn't be new to you, so I'll just talk about the most important part of this bean: public List getAllEmployees(). This method is an excellent example of how you can build your apps without knowing how the logic in the business layer is implemented. The only thing you have to know is that there is a service with a method getAllEmployees, and that this method returns you a list with all employees. You don't even need to know how hibernate works because you don't care as long as the service you call returns the list of Employees to you.

Now you have to set the properties in the faces-config, so that your bean knows where to get the Service.

<managed-bean>
<managed-bean-name>FacingHibernate</managed-bean-name>
<managed-bean-class>
com.blogspot.lucbors.view.backingbeans.FacingHibernateBackingBean
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>empServ</property-name>
<value>#{empServ}</value> <!--Inject this value from Spring-->
</managed-property>
</managed-bean>


Configuring your application to use Spring and Hibernate
Make sure that your application knows that you are using Spring for integration. So in the faces-config you should declare an application.
<application>
<!-- Install the Spring JSF integration -->
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>

In you deployment descriptor (web.xml) you have to create an extra context-parameter, an extra filter and an extra listener.

<context-param>
<param-name>contextConfigLocation</param-name>
<!-- core-empdemo.xml contains Service & Dao object
configuration as well as transaction demarcation -->
<param-value>
classpath:core-empdemo.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<filter>
<filter-name>HibernateFilter</filter-name>
<filter-class>
com.blogspot.lucbors.view.utils.HibernateSessionRequestFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>HibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


The core-empdemo.xml is a file that tells your application exactly where to get the service that you are using. You should get this file from your hibernate developer and place it on your classpath.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="employeeService"
class="com.blogspot.lucbors.core.model.service.impl.EmployeeServiceImpl"/>
</beans>


So now you are all set. It looks as if it is kind of compicated, but remember, it's configuration, and you only have to do that when you start a project ! Once you have it all up and running, just leave it alone.

The next thing you do is create a page with an ADF-table on it. You then bind that table to the backingbean.



Run the page, and it's working (if you included the Spring and hibernate libraries in your project)!!

Next time I'll write about the business and integration layer a little bit.

usefull resources:
http://wiki.apache.org/myfaces/Hibernate_And_MyFaces

Friday, September 28, 2007

New kid on the block !

It's been a quit month on my blog but I've been very busy "fooling around" lately.

That is what happens to you when you become a father for the first time. Less sleep......but tons of fun ! One thing that my daughter allready made clear to me is is that my time is no longer only available to Jdeveloper and ADF. Every time I find some minutes to do some research at home, she will start telling me that she wants to eat, or play, or that she want's some attention. I made it my personal goal to teach her (she's 8 weeks old now) ADF as soon as possible, so I get to spent more quality time with her ;-)

My daughter wasn't the only newborn. There actually is another one: "Oracle JDeveloper 11g Technical Preview 2 - (Build 4684)". It can be downloaded here.
It is the first preview which has a automated migration process for 10g apps.

Steve Muench announced it on his blog. You can find a link to the migration guide there as well. I'm curious to find out what will happen to the panel page which no longer exists in 11g but was the base of many 10g apps !

If I find the time I'll try to play with 11g preview 2 next couple of weeks.

Friday, August 31, 2007

Easy scrolling in a table

If you have a backgound in Oracle Forms, you'll really like this post, because you are used to these functions: "key-up, key-down, current-record-visual-attribute", and so on........Especially the arrow keys to scroll a table !

It is possible to implement this in an ADF application. It takes some time to figure out, but it works, at least I'm very close now.

Using some of the logic from one of my previous posts I managed to implement "easy scrolling".

It take some javascript;
0: make the row current after click. "makeCurrent()".
1: find out the key pressed "checkKey()".
2: do the up or down action "nextRow()" and "previousRow()".
3: make sure you don't loose focus "holdCurrentField()".

You'll have to add onclick="makeCurrent()" and onkeydown="checkKey()" to every column in you're table. This will cause the row become current when clicked on it and the onkeydown will implement the scrolling with the arrow keys.

At the moment onkeydown="checkKey(this,event,#{bindings.Employees1.rangeStart},#{bindings.Employees1.rangeSize});" , I'm not sure if I really need the range values in this solution, but I have something that I'm working on to make this solution more sophisticated.

The "current row" is highlighted by evaluating the rowKey of the row and the rowkey of the iterator: styleClass="#{row.rowKeyStr == bindings.Employees1Iterator.currentRowKeyString ? 'highligthSelectedRow' : ''}"
where 'highligthSelectedRow' is an entry in the css.



The project file can be downloaded here.

Please feel free to try this out and to post any comments if you have a better solution or if you like this one, or if you have additional solutions.

Monday, August 27, 2007

Demo projectfiles available online

Some of you bloggers have been asking for source code of the application. It took me a while to make this available online. One of the reasons is that blogger does not support file upload (other than images).

After googling around for a while, I decided to use googlepages. You can find the project files here. For now there's only a draft version of the MyFacesPopup and the PullDownMenu. Navigation is not yet working in this version of the Menu, but I'm sure you'll get it working.

In my comming posts I will put direct references to the correct version of the dwonloadable demo's.

Wednesday, July 25, 2007

Save limited space; use MyFaces popup's

Sometimes I wonder how to put all these visual elements on an already overloaded page. Customers have their needs for functionality, but sometimes just don't know when to say STOP. We need this, we need that ............ I wondered if all this functionality has to be available at any time, and if so, if it should be visible.

What if I was able to 'partially hide' elements, and bring them into view only if a user really needs them ? I used one of the Myfaces components. In this case the popup.

A Popup will only "popup" at the location where it is defined. It works more or less in a "now you see it, now you don't" way. The functionality in this popup works the way it should. By using the popup, I was able to add functionality to my page, without overloading the page with visual components. Below you see the page. It has (somewhere) functionality to customize the page.



If the mouse is over the "Customize Your Application" text, the popup is shown.



And the look and feel changes to................



You can find the taglib for the popup here.

Here's the code snippet you can use to render the popup:

<t:popup title="customize"
displayAtDistanceX="-220"
displayAtDistanceY="0"
closePopupOnExitingElement="false"
id="popup" rendered="true" >
<af:outputLabel value="Customize Your Application"
inlineStyle="font-size:x-small;"/>
<f:facet name="popup">
<af:panelHorizontal>
<af:panelBox text="customize">
<af:selectOneChoice label="Select Skin"
............................


Details on how to use the Myfaces components can be found in one of my other posts.

Thursday, July 12, 2007

Fun: Milleniumbug's are still around

I was sure that back in 1999 I found and coded my last fix for the milleniumbug. Maybe that was true for me, but even today they are around, even in brandnew products. In the new release of google analytics I found one.



If you open the extended calendar, they will tell you it's 1907...........
1907 was a great year for wine perhaps, but I dont think there was an internet back then.

However, analytics is a very usefull tool for me. And I'm sure they can fix it.

Wednesday, July 11, 2007

Total Recall.......DBA's go wild !!

Today Oracle launched the 11g database.

It's all about the yingyang of requirements and innovations.



If I just had the time I would tell you about it, but for now I'll just redirect you.


Read the press release here.

And read on the new features here.

And just for fun............ go here and Watch the July 11 Webcast.

It is the only way !!!

Friday, June 22, 2007

What's (on) your menu ?

Imagine a restaurant which serves great food, preferably your own favorite restaurant. Now imagine that this same restaurant, has your own personalized menu. Wouldn't that be great. You could just go there and eat whatever you feel like at that moment.

The same goes for the application you build. If you use ADF-Faces and a panelpage with menu facets to show the menu in your application, the framework tells you how your menu works, and almost what it looks like.

So this is what my menu looked like.



The ADF-faces menu has a couple of annoying features. First of all the size of the Menubar. If you have about 10 menu items (or less but with very long labels) the end users have to scroll to the right to see all items. You would easily miss the menu items on the far right. End users just love the pulldown menu's that they are used to. They use it in OracleForms, they use it in TwoLetterWord Office, and so on.

Secondly, the faces-config, in which the menu is configured will load only once.
Immagine what could happen if your menu is being constructed from a database table with roles and permissions per user: "An admistator revokes permission from a given users, and tells him to log off the system to activate this new privilige". Say what ?!. I'll explain this in a later post, and I will describe how to implement database driven menu security.

Here is how the pulldown menu can be implemented.

Copy lib's to be able to use myfaces menu.


Create the namespace, xmlns:t="http://myfaces.apache.org/tomahawk"
Create an extension filter in the web.xml

And this is my new menu.


So what about the "own personalized menu" that I mentioned in the beginning of this post ? I even found a way to fix that. Not rocketscience though; just use a switcher in the menu facets and add a "Customizer" to your application. Your menu and your look and feel wil change "on the fly". The customizer contains SelectOneChoice listboxes to set the values of skin and menutype:


<af:selectOneChoice label="Select Menu type"
value="#{sessionScope.menuType}"
onchange="form.submit();">


And in the page you use the switcher to display either of the menutypes.

<f:facet name="menu2">
<af:switcher facetName="#{sessionScope.menuType}"
defaultFacet="ADF-Faces">
<f:facet name="ADF-Faces">
<af:region id="menu2"
regionType="nl.kees.cursus.regions.common.UMMenu2"/>
</f:facet>
<f:facet name="My-Faces">
<af:region id="menu7"
regionType="nl.kees.cursus.regions.common.UMMenuPull"/>
</f:facet>
</af:switcher>
</f:facet>

After that it works just great. Below you see the 'deault' ADF look and feel.


And when you set your "own" customizations, here's what you get:


I really had fun creating this, and after showing this to some of my coworkers, even they liked it ;-)

Monday, June 11, 2007

Sliding into view

A couple of days ago some one asked me if it was possible to bind inline style properties to a backing bean using Expression Language. I knew this was possible so I explained him how to do that. This also was a nice opportunity to try out how an af:inputNumberSlider works. I wanted to use the value of the slider to set the fontsize in the rest of my example application.






It worked ! Here's how I did it.
First you have to drop the af:inputNumberSlider on your page. You also have to drop an af:outputText on your page. This textfield will contain the displayed text. If you want the page to use the value of the slider immediately, you have to set the autosubmit property of the slider to true. After that, give the slider an id and use this id in the partial triggers property of the inputtext.

Finally you have to bind the slider and the outputtext to a backingbean. In this bean you will read the slidervalue and use it to set the size of the text in the outputtext.

The source of the bean looks like this


public class UseSliderValues
{
private Integer sliderValue = 100;
private Integer sliderStartValue =100;

String text = "initial text";
String fontsize = "font-size:0%;";

public UseSliderValues() { }

public void setSliderStartValue(Integer sliderStartValue) {
this.sliderStartValue = sliderStartValue; }

public Integer getSliderStartValue() { return sliderStartValue; }

public Integer getSliderValue() { return sliderValue; }

public void valueChanged(ValueChangeEvent valueChangeEvent) {
this.sliderValue = (Integer)valueChangeEvent.getNewValue(); }

public String getFontsize() {
fontsize="font-size:"+(200-2*sliderValue)+"%;";
return fontsize; }

public String getText() {
if (sliderValue!=0) {
text="Your eyesight is "+sliderValue+ "%; you're able to read this"; }
else {
text="Are you sure ? With "+ sliderValue+"% eyesight you shouldn't be able to read anything except braille !!"; }
return text; }}


The source of the page will look something like this:


af:inputNumberSlider id="slider"
label="How good is your eyesight (0-100%) ?"
autoSubmit="true"
minimum="0" maximum="100"
value="#{RichComponents_backingbean.sliderStartValue}"
valueChangeListener="#{RichComponents_backingbean.valueChanged}"/>

af:outputText value="#{RichComponents_backingbean.text}"
partialTriggers="slider"
inlineStyle="#{RichComponents_backingbean.fontsize}"/>


Run the application and try some slider values (0% eyesight...........)






So now you have two solutions in one post: How to use a inputnumberslider and how to set the inlinestyle property through EL. I had fun doing this.

Monday, June 04, 2007

Whats new ?

Recently this blog was mentioned on 'blogs.oracle.com' and on Steve Muench's weblog . Thanks Steve ! I guess my weblog is getting more popular by the week ("I Love Google Analytics").

So I want to put some really new stuff here. I also want to post at least once every week..... Here's my challenge !

I want to write on templating, LOV's and other new features, but that takes time. And I'm not just doing stuff for my blog. I'm also working ;-)

But I'll see what I can do. First I'll try to isolate some solutions we had to implement in the prvious project. And if there's more time ......

Wednesday, May 16, 2007

One size fits all.

I've been playing with the Jdeveloper 11G technical preview during this week and it's a lot of fun. The new ADF-Faces contains some very nice sizing components.

So from now on you don't have to try every possible size for columns and panels. Just use panelsplitters and adf tables and have your end users try for themselves. Here are some examples that I just created. If the images are too small, just click on them.....



Compare the order of the columns in the table below with the order in the table above. You can just drag and drop them runtime.



If you use the panelsplitter (click on the arrow) you can hide a pane runtime. Look below..... the menu has disappeared.



You can also resize the panels and columns. There is no coding required at all !!!
Just drag the borders to the size you want.

See here for the panels....


And here for the columns....



Finally the date select isn't a popup window anymore and that's very nice as well.



I'll be playing around for the next couple of weeks (or will it be months) and try to post as many stuff as I can. I didn't supply any code because there's no coding involved at all. But for the disbelievers.........this is all..

<..af:panelSplitter >
<..f:facet name="first">
<...any stuff you like.../>
<../f:facet>
<..f:facet name="second">
<...any stuff you like.../>
<../f:facet>
<../af:panelSplitter>

Tuesday, May 08, 2007

JDeveloper 11G Technical Preview

Oracle released the JDeveloper 11G Technical Preview.


Want to know more on this Tech. Preview , then go to http://www.oracle.com/technology/products/jdev/11/index.html

Thursday, April 12, 2007

How to hide the * for required fields

Sometimes it is annoying to see the '*' in front of a required field.
If a customer demands the '*' to be removed, you really have a problem !
It seems to be impossible to remove it and a lot of people say that it is.....................

But here is your solution.

If you put the following line of code in your stylesheet, the '*' will not be displayed !

.xi {
display: none;
}

For outlining everything, you can use the ussual stuff.

More to come

Friday, January 26, 2007

Project planning

From september on I've been working hard on a very exiting project. Thats why it has been very quiet on my weblog. However, in this project we found a lot of briljant solutions for common problems.... You can decide to avoid problems... but you can also try to solve them. The latter is what we did. Some solutions will be posted here shortly. I've more time now, so I'll try to post every week from now on.

Hint................
  • Using a Mulitselect listbox to create an in clause in a sql-query

And lots more.