Tag Archives: ADF Faces

How to show multi-lines af:message

Environment (JDeveloper 11.1.2.0.0, ADF Faces)

In the last post, I have explained how to show af:message programatically. In some cases the user may need to show a multi-lines message, in this post I will explain how to do this.

af:message allows us to include a formatted text in the message, this can be done by surrounding the message text with <html> tags. So to show a multi-lines message, we can use <p> tag  in our message text. The method below displays three lines message.

public String shwoMultiLinesMessage() {
        StringBuilder builder = new StringBuilder(“<html> <body>”);
        builder.append(“<p>First Line</p>”);
        builder.append(“<p>Second Line</p>”);
        builder.append(“<p>Third Line</p> “);
        builder.append(“</body> </html>”);
        FacesMessage fm = new FacesMessage(builder.toString());
        fm.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, fm);
        return null;
    }

The result is af:message with three lines as shown in the image below:

mult-lines message

multi-lines message

Advertisements

2 Comments

Filed under ADF

How to show af:message programatically

Environment (JDeveloper 11.1.2.0.0, ADF Faces)
ADF Faces uses the standard JSF messaging API. JSF supports a built-in framework for messaging by allowing FacesMessage instances to be added to the FacesContext object using the addMessage(java.lang.String clientId, FacesMessage message) method. In general there are two types of messages that can be created:component-level messages, which are associated with a specific component based on any client ID that was passed to the addMessage method, and global-level messages, which are not associated with a component because no client ID was passed to the addMessage method.

in this post, I will show how to show af:message programatically.

  • global level message:

To show a global level message, use this method:

public String showMessage() {
        String messageText=”A prgramatic af:message”;
        FacesMessage fm = new FacesMessage(messageText);
        /**
         * set the type of the message.
         * Valid types: error, fatal,info,warning
         */
        fm.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, fm);
        return null;
    }

the code above will show the message in pop-up dialog as shown below.

pop-up global message

However, you can show the global message inline with the page, what you want to do is to change the inline attribute of the af:messages in your page, this component is created automatically for you when you create a page. The inline attribute controls whether to render the message list inline with the page or in a popup window, the default value is false. Normally the messages are rendered in a pop up. If this attribute is set to true, the messages list will be rendered inline with the page. To find the af:messages, open your page in the main window, from the structure window you can find it under f:view,af:document nodes. Your global message will be shown inline with page as shown below.

global message - inline with the page

 

  • component-level message:

To show a message inline with a component (i.e. associated with a specific UI component) you need to expose the UI component in the managed bean using the Binding property, then you can use this method:

public String showMessage() {
        String messageText=”A prgramatic af:message”;
        FacesMessage fm = new FacesMessage(messageText);
        /**
         * set the type of the message.
         * Valid types: error, fatal,info,warning
         */
        fm.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext context = FacesContext.getCurrentInstance();
        //departmentName is the binding property for our field.
        context.addMessage(getDepartmentName().getClientId(context), fm);
        return null;
    }

The code above will show the message associated with department name field as shown below:

component-level messages

13 Comments

Filed under ADF

Control row updatability – part 2

Environment (JDeveloper 11.1.2.0.0, ADF BC, ADF Faces)

In the previous post, I have shown how to control the row updatability based on some conditions. Another popular use case for row updatability is making the row or some attributes within the row only updatable while the row status is new, but after being successfully committed to the database they should become read-only. In this post I will show how to implement this use case in declarative and programmatic ways.

  • Declarative method:

The Updatable property controls that is available for each attribute within the entity and view objects has a While New option, we can set this property for single, multiple, or all attributes as shown below.

Updatable Property

 

  • Programmatic method:

we can override isAttributeUpdateable method in the EntityImpl class. If we want the entire row to be updatable while it is  new then override  isAttributeUpdateable method as shown below:

  public boolean isAttributeUpdateable(int i) {
        if (getEntityState()!=STATUS_NEW )
            return false;
        else
            return super.isAttributeUpdateable(i);
    }

If we want single or many attributes to be updatable while the row is new, then override  isAttributeUpdateable method as shown below:

public boolean isAttributeUpdateable(int i) {
        /**
         * ID is the attributeEnum.
         * you can add attributesEnum as required
         * by your use case
         */
        if (getEntityState()!=STATUS_NEW && i== ID)
            return false;
        else
            return super.isAttributeUpdateable(i);
    }

 

see also: Control row updatability – part 1.

Leave a comment

Filed under ADF

Control row updatability – part 1

Environment (JDeveloper 11.1.2.0.0, ADF BC, ADF Faces)

Sometimes developers want to make an entire row as read only based on some conditions, As an example assume that you have an application that allows users to apply for something, once the application is approved they are not allowed to modify any attribute instead they can only see their application, this can be done by setting the read only property for each attribute from the property inspector. However, doing this is a headache approach especially if you want to repeat this in many pages and your row contains many attributes.

To implement such similar case in effective approach, we can override the isAttributeUpdateable method either in the EntityImpl class or in the ViewRowImpl class. If you want your row to be non updatable regardless of the view object being used, then override the isAttributeUpdateable method in the EntityImpl class otherwise override the method in your ViewRowImpl class.

The steps required to do this are, (assumed we need to override the isAttributeUpdateable method in EntityImpl class).

  1. generate your custom EntityImpl class.
  2. Assumed that your EntityImpl class is opened in Jdeveloper main window, click on the source menu, then select Override methods  as shown below.

    Override isAttributeUpdateable method

  3. The Override methods window will open, select the isAttributeUpdateable method and click OK as shown below.

    Select isAttributeUpdateable method

  4. Now override your method based on your condition as shown below:

    public boolean isAttributeUpdateable(int i) {
//you can add your condition here
     //in this case Flag attribute indicates whether
    //an application is approved or not
if (this.getFlag().equals(“Y”))
return false;
else
return super.isAttributeUpdateable(i);
}


see also:  Control row updatability – part 2.

Leave a comment

Filed under ADF

How to control the location of the new row in af:table

Environment (JDeveloper 11.1.2.0.0, ADF BC, ADF Faces, hr schema)

When we add a new row in af:table,the default behavior is that the new row is added before the current row. Sometimes we may need to change this behavior. In this post I will show how we can add new row at different locations within our table, and automatically scrolling to that new row.

This post is based on hr schema (EMPLOYEES table) and assumed that you have already built your BC. The button used to add a new row has its PartialSubmit property set to true, and the table has its PartialTrigger property references the button’s id, also our table should have its DisplayRow property set to selected, the table binding in the managed bean is empTable (setEmpTable(RichTable empTable), getEmpTable()).

  1. To add a new row at the first location on the table use this method:   
    public String addRowAtFirst() {
    // Add event code here…
    CollectionModel tableModel = (CollectionModel)getEmpTable().getValue();
    JUCtrlHierBinding adfModel = (JUCtrlHierBinding)tableModel.getWrappedData();
    DCIteratorBinding dciter = adfModel.getDCIteratorBinding();
    NavigatableRowIterator nav=dciter.getNavigatableRowIterator();
    Row newRow = nav.createRow();
    newRow.setNewRowState(Row.STATUS_INITIALIZED);
    nav.insertRowAtRangeIndex(0, newRow);        dciter.setCurrentRowWithKey(newRow.getKey().toStringFormat(true));
    return null;
    }
  2. To add a new row at the end of the table use this method:   
    public String addRowAtLast() {
    // Add event code here…
    CollectionModel tableModel = (CollectionModel)getEmpTable().getValue();
    JUCtrlHierBinding adfModel = (JUCtrlHierBinding)tableModel.getWrappedData();
    DCIteratorBinding dciter = adfModel.getDCIteratorBinding();
    NavigatableRowIterator nav=dciter.getNavigatableRowIterator();
    Row newRow = nav.createRow();
    newRow.setNewRowState(Row.STATUS_INITIALIZED);
    Row lastRow = nav.last();
    int lastRowIndex = nav.getRangeIndexOf(lastRow);
    nav.insertRowAtRangeIndex(lastRowIndex+1, newRow);
    dciter.setCurrentRowWithKey(newRow.getKey().toStringFormat(true));
    return null;
    }
  3. To add a new row before the current selected row (default behavior) use this method:   
    public String addRowBefore() {
    // Add event code here…
    CollectionModel tableModel = (CollectionModel)getEmpTable().getValue();
    JUCtrlHierBinding adfModel = (JUCtrlHierBinding)tableModel.getWrappedData();
    DCIteratorBinding dciter = adfModel.getDCIteratorBinding();
    NavigatableRowIterator nav=dciter.getNavigatableRowIterator();
    Row newRow = nav.createRow();
    newRow.setNewRowState(Row.STATUS_INITIALIZED);
    nav.insertRow(newRow);        dciter.setCurrentRowWithKey(newRow.getKey().toStringFormat(true));
    return null;
    }
  4. To add a new row after the current selected row use this method:   
    public String addRowAfter() {
    // Add event code here…
    CollectionModel tableModel = (CollectionModel)getEmpTable().getValue();
    JUCtrlHierBinding adfModel = (JUCtrlHierBinding)tableModel.getWrappedData();
    DCIteratorBinding dciter = adfModel.getDCIteratorBinding();
    NavigatableRowIterator nav=dciter.getNavigatableRowIterator();
    Row newRow = nav.createRow();
    newRow.setNewRowState(Row.STATUS_INITIALIZED);
    Row currentRow = nav.getCurrentRow();
    int currentRowIndex = nav.getRangeIndexOf(currentRow);
    nav.insertRowAtRangeIndex(currentRowIndex+1, newRow);
    dciter.setCurrentRowWithKey(newRow.getKey().toStringFormat(true));
    return null;
    }

7 Comments

Filed under ADF

Display row number in af:table

Environment (JDeveloper 11.1.1.5.0, ADF Faces)

In this post, I will explain how to add an extra leading column to display the row’s number. This example assumed that we have oracle.adf.RichTable in our page and we need to add extra column to hold the row’s number for each row. The steps to do this are:

  1. From the structure window, right click on your first column and choose Insert before af:columncolumn from the menu.
  2. Still in the structure window, right click the newly created column and choose Insert inside af:column Output Text from the menu.
  3. The oracle.adf.RichTable component has an attribute called varStatus.  The VarStatus provides contextual information about the state of the component to EL expressions. For components that iterate, varStatus also provides loop counter information. The common properties on varStatus include:
    • “model” – returns the CollectionModel for this component.
    • “index” – returns the zero based row index. we will use this property later.
  4. Still in the structure window, click on the table, and from the property inspector expand the column group and check the name of the EL variable used to reference the varStatus information(default value is vs) as shown below.

    Table's varStatus attribute

  5. Still in the structure window, click on the output text which was created on step 2, and from the property inspector set the value attribute to #{vs.index+1}.
  6. Your column source should be like this:
    <af:column id=”c5″>
    <af:outputText value=”#{vs.index+1}” id=”ot1″/>
    </af:column>
  7. Run your page, and you will see the row number for each row.

6 Comments

Filed under ADF

How to Create a Custom JSF Validator

Environment (JDeveloper 11.1.1.5.0, ADF BC, ADF Faces, hr schema)

ADF Faces provides several validation types; UI component attributes validation, default ADF Faces validators, and custom ADF Faces validators. The last type (custom ADF Faces validators) enables you to create your own validation logic in a Java class then you can use it as a validator to your UI component. The custom validator can be created for a specific component in a single page, or can be created to be used in all pages in your application. In this example, I will explain how to build your own custom validator that can be used in all pages. This example based on hr schema, mainly on Employees table, and assumed that you already have built your BC. Our business rule is that the PHONE_NUMBER attribute should be at least 9 digits. The steps to build your own validator are:

  1. Create a Java class that implements the javax.faces.validator.Validator
    interface in your viewController project as shown below. In the name field enter “PhoneValidator”, enter your desired package, and in the Optional Attributes section click the green plus symbol to add the interface that this class should implement.

    PhoneValidator class

  2. After you have created the class, you will see the validate method to implement the interface. override this method as shown below.
    public void validate(FacesContext facesContext,
    UIComponent uIComponent,
    Object object)
    throws ValidatorException {
    //add your validation logic here
    String phone = object.toString();
    if (phone.length() < 9) {
    FacesMessage fm =
    new FacesMessage(“Phone number should be at least 9 digits”);
    throw new ValidatorException(fm);
    }
    }
  3. Now you need to register your validator in faces-config.xmlfile, locate this file in your viewController project then double click on it, after the file was opened in your main window click the overview tab, then select the validator link from the left hand side. Click on the green plus symbol to add your validator as shown below.

    register the Phonevalidator

  4. Now our validator is ready to use, create a page, drag and drop the EmployeeView1 from the data control, and select ADF form from the menu.
  5. Right click on the PhoneNumbe filed, and select insert inside Input Text → JSF Core → Validator. Once you add the validator, go to the property inspector palette, select the ValidatorId property then select our PhoneValidator from the list. your page source should look like this source snapshot.
    <af:inputText value=”#{bindings.PhoneNumber.inputValue}”
    label=”#{bindings.PhoneNumber.hints.label}”
    required=”#{bindings.PhoneNumber.hints.mandatory}”
    columns=”#{bindings.PhoneNumber.hints.displayWidth}”
    shortDesc=”#{bindings.PhoneNumber.hints.tooltip}”
    id=”it4″>
    <f:validator binding=”#{bindings.PhoneNumber.validator}”/>
    <f:validator validatorId=”phonevalidator”/>
    </af:inputText>
  6. Run your page and enter a phone number less than 9 digits, submit the form, the error message will be shown as below.

    error message shown after violate PhoneValidator

see also: Add business rule in the setter method of an entity attribute

9 Comments

Filed under ADF