Pages

Friday, December 14, 2007

Dynamic jsf page

In this example I made a simple jsf page where I can add or remove inputtext items and action buttons. It uses the pagedef of the page as input for the items and the buttons. This is how it looks


On the left side you have a panelFormLayout where we add the items on it. The panelFormLayout has a footer facet where we add the buttons. On the right side we have two selectOneChoice with 3 buttons. The first selectOneChoice is for the items and buttons which we can add. If we add an item we remove this entry in the add choice and add this entry in the remove choice. The Init button fills the add choice with the values of the pagedef.

The add method for putting values and actions on the jsf page

public String add() {
String item = add_item.substring(add_item.indexOf("_")+1);
if ( add_item.startsWith("value")) {
RichInputText input = new RichInputText();
input.setValueExpression("value",getValueExpression("#{bindings."+item+".inputValue}"));
input.setValueExpression("label",getValueExpression("#{bindings."+item+".hints.label}"));
input.setId(item);
form.getChildren().add(input);
addRemoveNewItemToList(add_item);
removeItemFromList(add_item);
}
if ( add_item.startsWith("action")) {

RichCommandButton button = new RichCommandButton();
button.setValueExpression("disabled",getValueExpression("#{!bindings."+item+".enabled}"));
button.setId(item);
button.setText(item);
MethodExpression me = getMethodExpression("#{bindings."+item+".execute}");
button.addActionListener(new MethodExpressionActionListener(me));
footer.getChildren().add(button);
addRemoveNewItemToList(add_item);
removeItemFromList(add_item);
}
return null;
}

the remove method

public String remove() {

String item = remove_item.substring(remove_item.indexOf("_")+1);
if ( remove_item.startsWith("value")) {

for (Iterator iterator = form.getChildren().iterator(); iterator.hasNext();) {
UIComponent component = (UIComponent) iterator.next();
if ( component.getId().equals(item)){
iterator.remove();
removeRemoveItemFromList(remove_item);
addNewItemToList(remove_item);
}
}
}
if ( remove_item.startsWith("action")) {

for (Iterator iterator = footer.getChildren().iterator(); iterator.hasNext();) {
UIComponent component = (UIComponent) iterator.next();
if ( component.getId().equalsIgnoreCase(item)){
iterator.remove();
removeRemoveItemFromList(remove_item);
addNewItemToList(remove_item);
}
}
}
return null;
}

the init method to fill choice

public String init() {
List values = new ArrayList();
values = getBindings().getAttributeBindings();
for (Iterator iterator = values.iterator(); iterator.hasNext();) {
Object o = iterator.next();
if (o != null) {
if (o instanceof FacesCtrlAttrsBinding) {
addNewItemToList("value_"+((FacesCtrlAttrsBinding)o).getName());
}
}
}
values = getBindings().getOperationBindings();
for (Iterator iterator = values.iterator(); iterator.hasNext();) {
Object o = iterator.next();
if (o != null) {
if (o instanceof FacesCtrlActionBinding) {
addNewItemToList("action_"+((FacesCtrlActionBinding)o).getName());
add_item = "action_"+((FacesCtrlActionBinding)o).getName();
}
}
}
return null;
}

Some other handy methods

private UIComponent getUIComponent(String name) {
FacesContext facesCtx = FacesContext.getCurrentInstance();
return facesCtx.getViewRoot().findComponent(name) ;
}

private MethodExpression getMethodExpression(String name) {
Class [] argtypes = new Class[1];
argtypes[0] = ActionEvent.class;
FacesContext facesCtx = FacesContext.getCurrentInstance();
Application app = facesCtx.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = facesCtx.getELContext();
return elFactory.createMethodExpression(elContext,name,null,argtypes);
}


private ValueExpression getValueExpression(String name) {
FacesContext facesCtx = FacesContext.getCurrentInstance();
Application app = facesCtx.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = facesCtx.getELContext();
return elFactory.createValueExpression(elContext, name, Object.class);
}



private BindingContainer getBindings() {
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = fc.getELContext();
ValueExpression valueExp = elFactory.createValueExpression(elContext, "#{bindings}", Object.class);
return (BindingContainer) valueExp.getValue(elContext);
}


public void addNewItemToList(String value)
{
if(value != null && !value.equals(""))
{
SelectItem si = new SelectItem();
si.setLabel(value);
si.setValue(value);
listOfItems.add(si);
listComponent.setValue(value);
}
}

public void removeItemFromList(String value)
{
if(value != null && !value.equals(""))
{
for(int i = 0; i < listOfItems.size(); i++)
{
SelectItem si = (SelectItem)listOfItems.get(i);
if(si.getValue().equals(value))
{
listComponent.setValue(null);
listOfItems.remove(i);
}
}
}
}


Here you have the example project for jdeveloper 11g. Thanks for larry.phillips on the otn forums for that the actions now works.

1 comment:

  1. Hi
    the project cannot running error " illegal internal package import use public api" in row
    import oracle.adfinternal.view.faces.model.binding.FacesCtrlActionBinding;
    import oracle.adfinternal.view.faces.model.binding.FacesCtrlAttrsBinding;
    I using window8 64bit jdev11.1.1.7 oracle 10g
    can you have me.
    thank so much
    will
    williamvn2002@gmail.com

    ReplyDelete