Please disable your adblock and script blockers to view this page

Search this blog

Showing posts with label Download. Show all posts
Showing posts with label Download. Show all posts

Tuesday 7 October 2014

Better User Interface- Oracle Alta UI for Oracle ADF 12.1.3

Great news for all ADF developers ,
Oracle has launched a design system for better user experience - Oracle Alta UI (much more than skin)

see press release- Oracle Announces New User Interface Design System for a More Engaging Customer Experience
As per documentation -

Oracle Alta UI is a new user interface design system that enables developers to create modern, visually pleasing, consistent, and engaging interfaces that can be easily distributed across all delivery channels.
The Oracle Alta UI design system provides a set of guidelines and best practices. The system is based on years of user experience and usability implementations and analysis by leading UI and design specialists.
Oracle Alta UI-based applications feature a simplified component structure and more open space to keep the focus on data.

See details of Oracle Alta UI- Oracle Alta UI

I have created a simple master detail page using Departments and Employees table of HR Schema using Jdev 12.1.3



by default skyros skin is applied in fusion web application, you can see this in trinidad-config.xml file under WEB-INF node




to apply Oracle Alta UI just change skin-family to alta


Now compare both UI , you will see a big difference

Full page-
Default Skin-

Alta UI-



See difference in af:inputDate and it's calendar
Default Skin-

 Alta UI- (icon is inside date field)

inputListofValues box is very attractive now-
Default Skin-

 Oracle Alta UI-
and magnifier icon is inside field now-

try it yourself and see difference in other components also
refer- Designing & Developing Oracle ALTA UI Apps
Sample ADF Application- Download
Thanks

Monday 4 August 2014

Uploading and downloading files from absolute server path in Oracle ADF (12.1.3)

Hello all
this post is about a very simple requirement -file handling (uploading and downloading various types of file) in ADF and it is needed very often to store file in absolute server path (actual path) and download from there

see step by step implementation -
  • I have created a simple table in HR schema to store uploaded file name ,path and content type
  • See sql script for this table-

     CREATE TABLE "FILE_UPD_DWN" 
       ( "FILE_NAME" VARCHAR2(50 BYTE), 
     "PATH" VARCHAR2(100 BYTE), 
     "CONTENT_TYPE" VARCHAR2(500 BYTE)
       )
    

  • Then prepare model using this table and drop on page as af:table, and an af:inputFile to select and upload file is used in page


  • Then create a ValueChangeListener on inputFile component to upload file to an actual path on server, and after upload a row is inserted in table to keep record of uploaded files

  • Bean Method to Upload File-


        /**Method to upload file to actual path on Server*/
        private String uploadFile(UploadedFile file) {
    
            UploadedFile myfile = file;
            String path = null;
            if (myfile == null) {
    
            } else {
                // All uploaded files will be stored in below path
                path = "D://FileStore//" + myfile.getFilename();
                InputStream inputStream = null;
                try {
                    FileOutputStream out = new FileOutputStream(path);
                    inputStream = myfile.getInputStream();
                    byte[] buffer = new byte[8192];
                    int bytesRead = 0;
                    while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                        out.write(buffer, 0, bytesRead);
                    }
                    out.flush();
                    out.close();
                } catch (Exception ex) {
                    // handle exception
                    ex.printStackTrace();
                } finally {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                    }
                }
    
            }
            //Returns the path where file is stored
            return path;
        }
    

    AMImpl method to insert record in table for Uploaded file




        /**Method to set file path and name
         * @param name
         * @param path
         */
        public void setFileData(String name, String path,String contTyp) {
            ViewObject fileVo = this.getFileUpdDwn1();
            Row newRow = fileVo.createRow();
            newRow.setAttribute("FileName", name);
            newRow.setAttribute("Path", path);
            newRow.setAttribute("ContentType", contTyp);
            fileVo.insertRow(newRow);
            this.getDBTransaction().commit();
            fileVo.executeQuery();
        }
    

    ValueChangeListener to execute all methods -




        /*****Generic Method to Get BindingContainer**/
        public BindingContainer getBindingsCont() {
            return BindingContext.getCurrent().getCurrentBindingsEntry();
        }
    
        /**
         * Generic Method to execute operation
         * */
        public OperationBinding executeOperation(String operation) {
            OperationBinding createParam = getBindingsCont().getOperationBinding(operation);
            return createParam;
    
        }
    
        /**Method to Upload File ,called on ValueChangeEvent of inputFile
         * @param vce
         */
        public void uploadFileVCE(ValueChangeEvent vce) {
            if (vce.getNewValue() != null) {
                //Get File Object from VC Event
                UploadedFile fileVal = (UploadedFile) vce.getNewValue();
                //Upload File to path- Return actual server path
                String path = uploadFile(fileVal);
                System.out.println(fileVal.getContentType());
                //Method to insert data in table to keep track of uploaded files
                OperationBinding ob = executeOperation("setFileData");
                ob.getParamsMap().put("name", fileVal.getFilename());
                ob.getParamsMap().put("path", path);
                ob.getParamsMap().put("contTyp", fileVal.getContentType());
                ob.execute();
                // Reset inputFile component after upload
                ResetUtils.reset(vce.getComponent());
            }
        }
    

  • Now run application and select files and see- 


  • See uploaded files in folder


  • I have seen that developers often use servlet to download and open file in browser window using HTTP response , but no need to to do this as ADF provides built in component for this <af:fileDownloadActionListener> that automatically generate http response
  • Now Upload part is complete , for download functionality added a link in table column and dropped an af:fileDownloadActionListener inside link and set properties for DownloadActionListener



  • See the code in Download Listener

  •     /**Method to download file from actual path
         * @param facesContext
         * @param outputStream
         */
        public void downloadFileListener(FacesContext facesContext, OutputStream outputStream) throws IOException {
            //Read file from particular path, path bind is binding of table field that contains path
            File filed = new File(pathBind.getValue().toString());
            FileInputStream fis;
            byte[] b;
            try {
                fis = new FileInputStream(filed);
    
                int n;
                while ((n = fis.available()) > 0) {
                    b = new byte[n];
                    int result = fis.read(b);
                    outputStream.write(b, 0, b.length);
                    if (result == -1)
                        break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            outputStream.flush();
        }
    

  • Now run application and see how Upload and download works 

Happy Learning :) Sample ADF Application

Next Post is this series - (Must Read)
Uploading mulitiple files to server path in Oracle ADF using af:inputFile
Uploading and downloading files from database (BLOB) in Oracle ADF

Friday 1 August 2014

Exporting viewObject data in text file using af:fileDownloadActionListener in Oracle ADF (12.1.3)

Hello All
This post is about using af:fileDownloadActionListener to generate file on run-time, suppose i have a viewObject and i want to export it's data in CSV or plain text so for this requirement we can generate file at run-time and send it to client UI to download

What is af:fileDownloadActionListener-
as per oracle docs-
The fileDownloadActionListener tag is a declarative way to allow an action source (<commandButton>, <commandLink>, etc.) to programatically send the contents of a file to the user, optionally with a specific content type and filename. Since file downloads must be processed with an ordinary request - not XMLHttp AJAX requests - this tag forces partialSubmit to be false on the parent component, if it supports that attribute.
The fileDownloadActionListener uses the native (browser built-in) filedownload popup, so this popup cannot be configured.

In this post i am using Departments table of HR schema



  • Prepare model part using Departments table and drop it on page as a table and add a button to UI for downloading


  • drop af:fileDownloadActionListener as child of button and set it's property as contentType, method , fileName 


  • Now see code written in download Listener-

  •     /**Method to get BindingsContainer for current page
         * @return
         */
        public BindingContainer getBindingsCont() {
            return BindingContext.getCurrent().getCurrentBindingsEntry();
        }
    
        /**Method to download ViewObject's data in plain text file
         * @param facesContext
         * @param outputStream
         * @throws UnsupportedEncodingException
         * @throws IOException
         */
        public void fileDownloadListener(FacesContext facesContext,
                                         OutputStream outputStream) throws UnsupportedEncodingException, IOException {
            OutputStreamWriter w = new OutputStreamWriter(outputStream, "UTF-8");
            //Get itertaor from bindings
            DCIteratorBinding deptIter = (DCIteratorBinding) getBindingsCont().get("Departments1Iterator");
            //Get ViewObject from Iterator
            ViewObjectImpl vo = (ViewObjectImpl) deptIter.getViewObject();
            ViewAttributeDefImpl[] attrDefs = vo.getViewAttributeDefImpls();
            int count = 0;
            RowSetIterator rsi = vo.createRowSetIterator(null);
            while (rsi.hasNext()) {
                Row nextRow = rsi.next();
                if (nextRow != null) {
                    // Code to iterate over ViewObject's column to get all columns value at runtime
                    for (ViewAttributeDefImpl attrDef : attrDefs) {
                        byte attrKind =
                            attrDefs[count].getAttributeKind(); //checks attribute kind for each element in an array of AttributeDefs
                        if (attrKind != AttributeDef.ATTR_ASSOCIATED_ROW &&
                            attrKind != AttributeDef.ATTR_ASSOCIATED_ROWITERATOR) {
                            String columnName = attrDef.getName();
                            w.write(columnName + " - " + nextRow.getAttribute(columnName) + "  ");
                        }
                    }
                    // Code to create new line text line for new Row
                    w.write(System.getProperty("line.separator"));
                }
            }
            //Flush the writer after wrting file
            w.flush();
        }
    }
    

  • Run this application and click on download button, browser download box appears , open downloaded file and see how your data appears in text file, to export data in a pdf file you have to generate PDF file using some API then you can download it in same way


Cheers:) Happy Learning

Monday 30 June 2014

Using Star Rating component (dvt:ratingGauge) in ADF 12c (12.1.3 new component)

Hello all
As ADF 12.1.3. is out , there is lot of enhancement in UI layer, component for Rating is available in this release i;e rating gauge (dvt:ratingGauge)
see how this rating gauge look like-

1.XML Source- Simple Rating Gauge with Star Symbol

<dvt:ratingGauge id="ratingGauge2" value="2" minimum="1" maximum="5" inlineStyle="width:300px;height:80px;"/>

2. XML Source- Rating Gauge with Circular Symbol


<dvt:ratingGauge id="ratingGauge2" value="2" minimum="1" maximum="5" inlineStyle="width:300px;height:80px;"
                     shape="circle" inputIncrement="half" readOnly="false"/>


2. XML Source- Rating Gauge with Circular Symbol, Rectangular Unselected Symbol



<dvt:ratingGauge id="ratingGauge2" value="2" minimum="1" maximum="5" inlineStyle="width:300px;height:80px;"
                     shape="circle" inputIncrement="half" readOnly="false" unselectedShape="rectangle"/>

Sample Application Based on Departments Table of Default HR Schema



  • Added a column in HR's Departments table for Rating


  • now create model using Departments table and drop on page (page fragment in bounded taskflow)as table and form, select Rating attribute from Data Control and drop as Gauge-->Rating Gauge(Minimum-0 Maximum-9)
  • see on page it is ready to show Rating of Department, but still not able to take input


  • By default rating gauge is readonly means it doesn't take input from user, set readonly to false and set increment (full or half) values
  • So i have tried this, but when i select any rating and commit data, it doesn't reflect changes in Database table, it is still showing previously saved value
  • i don't know why this is happening, so i have used valueChangeListener and set new rating in current row of Department, in this way it is working fine

  •     /**ValueChange Listener to SetRating
         * @param vce
         */
        public void ratingVCE(ValueChangeEvent vce) {
            if (vce.getNewValue() != null) {
                System.out.println("New Rating -" + vce.getNewValue());
                DCIteratorBinding iter = (DCIteratorBinding) getBindings().get("Departments1Iterator");
                iter.getViewObject().getCurrentRow().setAttribute("Rating", vce.getNewValue());
            }
        }
    

  • Now run and enjoy new rating gauge :)

Happy Learning :) Download- Sample ADF Application


Tuesday 20 May 2014

Blocking row navigation in af:table , synchronize row selection with model in case of validation failure- Oracle ADF

In ADF we often work on editable af:table and when we use af:table to insert ,update or delete data, it is normal to use some validation
but problem is when some validation failure occurs on page (in af:table) ,still we can select another row and it shows as currently selected Row
this is a bit confusing for user as Row Selection of af:table is not synchronized with model or binding layer

See Problem- 
  • I have an editable table on page


  • Added a validation to check negative value in field of LocationId, now navigate to another row


  • See selected focus is on Academic, but problem is when there is validation failure, why it is showing other row as selected ? 



  • If you check in ViewObject , you will find that row with DepartmentName Human Resource is current row

ADF framework provides a property in af:table to control navigation in af:table when there is some error or validation failure- blockRowNavigationOnError
See in oracle docs about this proprty-

Valid Values: always, never, auto


Whether we want to block row navigation in case of validation failure.
This is when you select a row and do some editing inside the table or in a related form, and this editing causes some validation failures. At this time, if you click on a different row in table, we want to block you from moving to the new row.
possible values are: always, never and auto. default value is auto.

  • always means we block the row navigation
  • never means we don't block and let the row navigation happen
  • auto means the framework will make the decision



by default in af:tabel it's value is <auto>


Change it to <always> and now see behavior on page


 now if you try to select another row, it is not get selected and selected focus is on row with validation

Sample ADF Application-Download
Cheers - Happy Learning :-)

Saturday 8 March 2014

Launching browser print dialog using simple javascript function in ADF

Hello All ,
This posts talks about a requirement of printing a simple page (not much component as, form,tree,etc & not much data)
you can use a simple one liner javascript function to invoke browser's print dialog.

  • there is a page with Departments table on it, and a button to print this page

  • Called this simple javascript function on button click to open print dialog

  • window.print();
    

  • to execute javascript through managed bean use this method 



  •     /**Method to execute Javascript
         * @param javascriptCode
         */
        public static void runJavaScriptCode(String javascriptCode) {
            FacesContext facesCtx = FacesContext.getCurrentInstance();
            ExtendedRenderKitService service = Service.getRenderKitService(facesCtx, ExtendedRenderKitService.class);
            service.addScript(facesCtx, javascriptCode);
        }
    

  • click on print button- In Google Chrome

In Mozilla-




after printing, the page look like this
Sample ADF Application- Download
Cheers :-)

Monday 8 July 2013

Create new look up data using List of Values (LOVs) in Oracle ADF


While working on project , I have seen such type of LOV that have a option of create Lov Value at selection time, this is quite good, as if desired value is not available in list then user can create on that time.

This type of list looks like this


It means if there is no company available in list you need not to go on Company form, user can create it directly from here.
Doing this in ADF is quite simple , in this tutorial i am taking example of Oracle default HR schema (Employees and Departments) table-
Implementation Steps-
  • Create business components from Department and Employees tabl


  •  Now create LOV on DepartmentId of employees ViewObject from Department VO



  • Go to UI Hints tab of LOV and select Combo Box with List of Values

  •  Now drag fields of Employee from DataControl to page as form
  •  Select Department Id Lov and go to structure window, and drop a link in customActions facet of  af:inputComboboxListOfValues
  • Now drag a popup on page and drag Department VO on af:dialog as form to create new department. and other things are same as normal form

  • Bind this popup to bean and create a ActionListener on the link inside facet to invoke createInsert of department table

  • package lookup.view.bean;
    
    import java.io.Serializable;
    
    import javax.faces.context.FacesContext;
    import javax.faces.event.ActionEvent;
    
    import oracle.adf.model.BindingContext;
    
    import oracle.adf.view.rich.component.rich.RichPopup;
    
    import oracle.adf.view.rich.event.DialogEvent;
    
    import oracle.binding.BindingContainer;
    import oracle.binding.OperationBinding;
    
    import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
    import org.apache.myfaces.trinidad.util.Service;
    
    public class LookupDataBean implements Serializable {
        private RichPopup deptPopUpBind;
    
        public LookupDataBean() {
        }
    
        public BindingContainer getBindings() {
            return BindingContext.getCurrent().getCurrentBindingsEntry();
        }
    
        private void showPopup(RichPopup pop, boolean visible) {
            try {
                FacesContext context = FacesContext.getCurrentInstance();
                if (context != null && pop != null) {
                    String popupId = pop.getClientId(context);
                    if (popupId != null) {
                        StringBuilder script = new StringBuilder();
                        script.append("var popup = AdfPage.PAGE.findComponent('").append(popupId).append("'); ");
                        if (visible) {
                            script.append("if (!popup.isPopupVisible()) { ").append("popup.show();}");
                        } else {
                            script.append("if (popup.isPopupVisible()) { ").append("popup.hide();}");
                        }
                        ExtendedRenderKitService erks =
                            Service.getService(context.getRenderKit(), ExtendedRenderKitService.class);
                        erks.addScript(context, script.toString());
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public void createDept(ActionEvent actionEvent) {
            BindingContainer bindings = getBindings();
            OperationBinding ob = bindings.getOperationBinding("CreateInsert");
            ob.execute();
            showPopup(deptPopUpBind, true);
        }
    
        public void DeptDialogListener(DialogEvent dialogEvent) {
            FacesContext fct = FacesContext.getCurrentInstance();
            if (dialogEvent.getOutcome().name().equals("ok")) {
                BindingContainer bindings = getBindings();
                OperationBinding ob = bindings.getOperationBinding("Commit");
                ob.execute();
    
            }
        }
    
        public void setDeptPopUpBind(RichPopup deptPopUpBind) {
            this.deptPopUpBind = deptPopUpBind;
        }
    
        public RichPopup getDeptPopUpBind() {
            return deptPopUpBind;
        }
    }
    

  • Now run this application and click on Lov of DepartmentId, you will see your link there to create Department


  • Now see that how many departments are listed currently in LOV

  • Now click on Add Department link and add a department
  •  Again see the listed departments- Oracle ADF Tutorial is added in now list
 this is how you can use this beautiful feature in your LOV-
Sample ADF Application- Download

Thursday 27 June 2013

Using af:poll to refresh and push data in page and databound table in ADF

Poll component delivers poll event to server at fixed intervals, we use poll in adf as an alternative of ADS (Active Data Service), this is very simple example of pushing data to page at some fix interval.
Basically af:poll component push data to UI from server.

  • This example contains a page with an af:table binded to Department VO, and I have used a poll component to refresh table periodically.

  • and defined pollListener on af:poll component that sends request to server in every 4 sec, and table get refreshed







  • Other approach to actively push data is ADS, but af:poll is still in use , to refresh table i have written in poll listener

  •         AppModuleAMImpl am = (AppModuleAMImpl)resolvElDC("AppModuleAMDataControl");
    
            ViewObject vo = am.getDepartment1();
            vo.executeQuery();
            i = i + 1;
            this.refreshInfo = "Data Reloaded-" + i+"  Total Row-->"+vo.getRowCount();
            AdfFacesContext.getCurrentInstance().addPartialTarget(refrshMsgBind);
    

  • See the jspx page source code-

  • <?xml version='1.0' encoding='UTF-8'?>
    <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
              xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
        <jsp:directive.page contentType="text/html;charset=UTF-8"/>
        <f:view>
            <af:document title="activePushing.jspx" id="d1">
                <af:messages id="m1"/>
                <af:form id="f1">
                    <af:panelBox id="pb1" showDisclosure="false" text="Active Data Pushing">
                        <f:facet name="toolbar">
                            <af:activeOutputText value="#{ActiveDataPushing.refreshInfo}" id="aot1"
                                                 inlineStyle="font-weight:bold;color:red;"
                                                 binding="#{ActiveDataPushing.refrshMsgBind}"/>
                        </f:facet>
                        <af:table value="#{bindings.Department1.collectionModel}" var="row"
                                  rows="#{bindings.Department1.rangeSize}"
                                  emptyText="#{bindings.Department1.viewable ? 'No data to display.' : 'Access Denied.'}"
                                  fetchSize="#{bindings.Department1.rangeSize}" rowBandingInterval="1"
                                  selectedRowKeys="#{bindings.Department1.collectionModel.selectedRow}"
                                  selectionListener="#{bindings.Department1.collectionModel.makeCurrent}"
                                  rowSelection="single" id="t1" styleClass="AFStretchWidth" contentDelivery="immediate">
                            <af:column sortProperty="#{bindings.Department1.hints.DepartmentId.name}" sortable="true"
                                       headerText="#{bindings.Department1.hints.DepartmentId.label}" id="c1" width="103">
                                <af:inputText value="#{row.bindings.DepartmentId.inputValue}"
                                              label="#{bindings.Department1.hints.DepartmentId.label}"
                                              required="#{bindings.Department1.hints.DepartmentId.mandatory}"
                                              columns="#{bindings.Department1.hints.DepartmentId.displayWidth}"
                                              maximumLength="#{bindings.Department1.hints.DepartmentId.precision}"
                                              shortDesc="#{bindings.Department1.hints.DepartmentId.tooltip}" id="it1"
                                              readOnly="true">
                                    <f:validator binding="#{row.bindings.DepartmentId.validator}"/>
                                    <af:convertNumber groupingUsed="false"
                                                      pattern="#{bindings.Department1.hints.DepartmentId.format}"/>
                                </af:inputText>
                            </af:column>
                            <af:column sortProperty="#{bindings.Department1.hints.DepartmentName.name}" sortable="true"
                                       headerText="#{bindings.Department1.hints.DepartmentName.label}" id="c2" width="107">
                                <af:inputText value="#{row.bindings.DepartmentName.inputValue}"
                                              label="#{bindings.Department1.hints.DepartmentName.label}"
                                              required="#{bindings.Department1.hints.DepartmentName.mandatory}"
                                              columns="#{bindings.Department1.hints.DepartmentName.displayWidth}"
                                              maximumLength="#{bindings.Department1.hints.DepartmentName.precision}"
                                              shortDesc="#{bindings.Department1.hints.DepartmentName.tooltip}" id="it2"
                                              readOnly="true">
                                    <f:validator binding="#{row.bindings.DepartmentName.validator}"/>
                                </af:inputText>
                            </af:column>
                            <af:column sortProperty="#{bindings.Department1.hints.ManagerId.name}" sortable="true"
                                       headerText="#{bindings.Department1.hints.ManagerId.label}" id="c3" width="105">
                                <af:inputText value="#{row.bindings.ManagerId.inputValue}"
                                              label="#{bindings.Department1.hints.ManagerId.label}"
                                              required="#{bindings.Department1.hints.ManagerId.mandatory}"
                                              columns="#{bindings.Department1.hints.ManagerId.displayWidth}"
                                              maximumLength="#{bindings.Department1.hints.ManagerId.precision}"
                                              shortDesc="#{bindings.Department1.hints.ManagerId.tooltip}" id="it3"
                                              readOnly="true">
                                    <f:validator binding="#{row.bindings.ManagerId.validator}"/>
                                    <af:convertNumber groupingUsed="false"
                                                      pattern="#{bindings.Department1.hints.ManagerId.format}"/>
                                </af:inputText>
                            </af:column>
                            <af:column sortProperty="#{bindings.Department1.hints.LocationId.name}" sortable="true"
                                       headerText="#{bindings.Department1.hints.LocationId.label}" id="c4" width="105">
                                <af:inputText value="#{row.bindings.LocationId.inputValue}"
                                              label="#{bindings.Department1.hints.LocationId.label}"
                                              required="#{bindings.Department1.hints.LocationId.mandatory}"
                                              columns="#{bindings.Department1.hints.LocationId.displayWidth}"
                                              maximumLength="#{bindings.Department1.hints.LocationId.precision}"
                                              shortDesc="#{bindings.Department1.hints.LocationId.tooltip}" id="it4"
                                              readOnly="true">
                                    <f:validator binding="#{row.bindings.LocationId.validator}"/>
                                    <af:convertNumber groupingUsed="false"
                                                      pattern="#{bindings.Department1.hints.LocationId.format}"/>
                                </af:inputText>
                            </af:column>
                        </af:table>
                        <af:poll id="p1" pollListener="#{ActiveDataPushing.pollListenerActive}" interval="4000"
                                 timeout="5000"/>
                    </af:panelBox>
                </af:form>
            </af:document>
        </f:view>
    </jsp:root>
    

  • Run your application, and do changes from Database and see updated UI at every 4 sec. :-)
 Reloading- 26th times-
 Reloading- 33th times-
 Reloading- 40th times-