switcher, работающий в hGrid
Видимо, это особенность совместимости switcher и hGrid. Решение:hGrid не перерисовывется при фильтрации данных
1. Не изменяя SQL во VO, создать транзиторный атрибут с названием, например, swTran (Type: String, Updatable: Always);
2. В модуле VORowImpl изменить функцию-геттер так, чтобы она возвращала значение нашего параметра в зависимости от атрибута myCond:
public String getSwTran() { Number i = getmyCond(); String cf = ""; if (i.intValue() == 0){ return cond1; }else{ return cond2; } }
Решение: перенести всю логику обертывания VO в условия в processRequest. И, как рекомендуется в гайде, после вызова одноименного метода родительского класса, прописатьиспользование атрибутов из VO разных уровней в атрибутах бина (например, построение Destination URI)
OAHGridBean hGrid = (OAHGridBean) webBean.findIndexedChildRecursive("Grid"); if (hGrid != null) { hGrid.prepareForRendering(pageContext); hGrid.setAutoQuery(false); }
Необходимо соблюдение трех условий: 1) используемые атрибуты присутствуют во ВСЕХ уровнях, там, где они не имеют физического смысла, делаем Transient; 2) алиасы параметров должны быть идентичны с учетом регистра; 3) в атрибутах бина View Instance и View Attribute должен быть прописан любой уровень и параметр, имеющий физический смысл.рекурсивное создание уровней hGrid
Если сущность завязана сама на себя по id = parent_id, то может потребоваться автоматическое достраивание уровней hGrid. Решение:
1. Создаем VL с отношением id = parent_id c отношением 0..1 to *;
2. Добавляем второй экземпляр VO нижнего уровня в AM через связь с созданным VL
безусловный переход на страницу
3. Достраиваем в PG дерево hGrid:
Здесь CommentLevel - ветка нижнего уровня с View Instance = Comment3VO1, ChildCommentLevel - создаваемая рекурсивно ветка с View Instance = Comment3VO2, CommentsLevel - узел с View Link Instance = CommentRecursiveVL1. Особое внимание - на узел RecursiveLink, в котором View Link Instance = CommentRecursiveVL1. Для него необходимо также задать параметр Ancestor Node = /oracle/apps/.../путь к пакету/<имя_страницы>.<имя_узла> - это необходимо для зацикливания при построении новых уровней. В нашем случае <имя_узла> = CommentsLevel.
перерисовка страницы с hashmappageContext.forwardImmediately( "OA.jsp?page=/oracle/apps/xxx/xxx1/webui/MyPG", null, OAWebBeanConstants.KEEP_MENU_CONTEXT, null, null, true, // retain AM OAWebBeanConstants.ADD_BREAD_CRUMB_NO);
обработка исключенияHashMap params = new HashMap(10); params.put("wPrm1", pageContext.getParameter("prm1")); params.put("wPrm2", pageContext.getParameter("prm2")); params.put("wPrm3", pageContext.getParameter("prm3")); pageContext.forwardImmediatelyToCurrentPage( params, false, OAWebBeanConstants.ADD_BREAD_CRUMB_NO); ... public void processRequest{ ... (OAPageContext pageContext, OAWebBean webBean) pageContext.getParameter("wPrm1")); ... }
invokeMethod с полными параметрамиtry{ OAApplicationModule am = pageContext.getApplicationModule(webBean); OADBTransaction tran = (OADBTransaction)am.getTransaction(); prm = tran.getMyPRM(); } catch (SQLException e) { throw OAException.wrapperException(e); }
оборачивание VO в ограниченияOAApplicationModule am = pageContext.getApplicationModule(webBean); Serializable[] prm_values = {myNum, myStr}; Class[] prm_classes = {Number.class, String.class}; am.invokeMethod("MyProc", prm_values, prm_classes);
программное изменение заголовка у webbeanpublic void initQuery(Number Id, String Str) { setWhereClause(null); setWhereClauseParams(null); setWhereClause("ent_id = :1 and ent_name = :2"); setWhereClauseParam(0, Id); setWhereClauseParam(1, Str); executeQuery(); }
вызов DB процедурыString someTitle = "title1"; ((OAPageLayoutBean)webBean).setTitle(someTitle);
содержимое колонки по центру (hGrid)OADBTransaction tran = getOADBTransaction(); OracleCallableStatement cStmt = null; StringBuffer callSt = new StringBuffer(); callSt.append("begin XXX_PKG.set_params("); callSt.append("pv_name => :1, "); callSt.append("pv_id => :2, "); callSt.append("pv_date => :3)"); callSt.append("; end;"); try { cStmt = (OracleCallableStatement) tran.createCallableStatement(callSt.toString(), tran.DEFAULT); cStmt.setString(1, prmUser); cStmt.setNUMBER(2, prmID); cStmt.setString(3, prmDate); cStmt.execute(); cStmt.close(); } catch (SQLException sqle) { throw OAException.wrapperException(sqle); }
динамическое создание View Objectprivate void getColCentered(OAPageContext pageContext, OAWebBean webBean, OAHGridBean hGrid) DataObjectList columnFormats = hGrid.getColumnFormats(); DictionaryData columnFormat = null; int childIndex[] = new int[] { pageContext.findChildIndex(hGrid, "Column1"), pageContext.findChildIndex(hGrid, "Column2"), pageContext.findChildIndex(hGrid, "Column3"), }; for (int i: childIndex) { columnFormat = (DictionaryData)columnFormats.getItem(i); columnFormat.put(COLUMN_DATA_FORMAT_KEY, ICON_BUTTON_FORMAT); } }
конвертирование строки в объект oracle.jbo.domain.DateStringBuffer strBuf = new StringBuffer(); strBuf.append("select p from (select 0 p from dual "); strBuf.append("union "); strBuf.append("select 1 from dual)"); ViewObject myVO = am.createViewObjectFromQueryStmt("myVO", strBuf.toString()); myVO.setWhereClause("p = :1"); myVO.setWhereClauseParam(0, "0"); myVO.executeQuery(); myVO.first(); OAMessageChoiceBean mcBean = (OAMessageChoiceBean)webBean.findChildRecursive("Test"); mcBean.setValue(pageContext, (String)myVO.getCurrentRow().getAttribute(0)); myVO.remove();
очистка датасета VO (итератор)import java.text.SimpleDateFormat; import java.text.DateFormat; import oracle.cabo.ui.data.DataObjectList; import oracle.cabo.ui.data.DictionaryData; public void dateTest(){ String dateStr = "11.01.2013"; DateFormat df; df = new SimpleDateFormat("dd.MM.yyyy"); java.util.Date tmp = null; tmp = df.parse(dateStr); oracle.jbo.domain.Date resDate = new oracle.jbo.domain.Date(new java.sql.Date(tmp.getTime())); }
очистка датасета VO (метод)public void clearVO(){ MyVOImpl MyVO = getMyVO1(); int rowCount = MyVO.getRowCount(); RowSetIterator deleteIter = MyVO.createRowSetIterator("deleteIter"); if (rowCount > 0) { deleteIter.setRangeStart(0); deleteIter.setRangeSize(rowCount); for (int i = rowCount - 1; i > -1; i--) { MyVORowImpl row = (MyVORowImpl)deleteIter.getRowAtRangeIndex(i); row.remove(); } } deleteIter.closeRowSetIterator(); }
поиск записи в VOsingleVO.executeEmptyRowSet();
построение мастер-детали в компоненте tableCausesVOImpl causeVO = getCausesVO1(); if (!causeVO.isPreparedForExecution()){ causeVO.setMaxFetchSize(0); } causeVO.executeQuery(); causeVO.setRangeStart(0); causeVO.setRangeSize(causeVO.getRowCount()); Number causeId = new Number(1); OADBTransaction transaction = getOADBTransaction(); Key keyCauseId = new Key(new Object[] {causeId}); // 1 - макс. количество возвращаемых записей Row causes[] = causeVO.findByKey(keyCauseId, 1); if (causes != null && causes.length > 0) { CausesVORowImpl causeRowVO = (CausesVORowImpl)causes[0]; ... }
1) добавляем атрибут Expand типа String во VO-родитель и в запросе устанавливаем его константой 'N'. Детализация будет отображена только для строк, где (Expand is not null). N - по умолчанию деталь свернута, Y - развернута;форматирование с помощью интерфейса Formatter
2) создаем View Link (MyVL), которым будут связаны данные, добавляем его и связь с дочерней таблицей в Application Module;
3) родительская таблица: параметр Detail View Attribute = Expand;
4) создаем бин детализации: правый клик по бину родительской таблицы - New - detail. В иерархии table components - detail создаем table layout, в нем создаем table. Можно и без первого, но он может потребоваться для добавления управляющих элементов в деталь;
5) дочерняя таблица: параметр Detail View Attribute = <имя атрибута, через который связывается родительская таблица>, View Link Instance = <имя экземпляра VL из Application Module>
Альтернативный метод связывания мастера и детали программно:
public void setMasterDetailLink(OAPageContext pageContext, OAWebBean webBean) { OATableBean masterTable = (OATableBean)webBean.findChildRecursive("MasterTable"); if (masterTable != null) { masterTable.setAttributeValue(CHILD_VIEW_ATTRIBUTE_NAME, "DetailId"); masterTable.setAttributeValue(VIEW_LINK_NAME, "MyVL1"); masterTable.setAllDetailsEnabled(true); } OATableBean detailTable = (OATableBean)webBean.findChildRecursive("DetailTable"); if (detailTable != null) { detailTable.setAttributeValue(CHILD_VIEW_ATTRIBUTE_NAME, "MasterId"); detailTable.setAttributeValue(VIEW_LINK_NAME, "MyVL1"); detailTable.clearCache(pageContext); } }
очистка VO при использовании retainAM=Yprivate void setColumnsFormat(OAPageContext pageContext, OAWebBean webBean, OAHGridBean hGrid){ int i; String format = "#,##0;-#,##0"; ArrayList<OAMessageStyledTextBean> columns = new ArrayList<OAMessageStyledTextBean>(); Formatter formatter = new OADecimalValidater(format, format); String columnNames[] = new String[] {"Col1", "Col2", "Col3"}; for (String str: columnNames){ OAMessageStyledTextBean col = (OAMessageStyledTextBean) webBean.findChildRecursive(str); if (col != null) columns.add(col); } for (i = 0; i<columns.size(); i++){ OAMessageStyledTextBean col = columns.get(i); col.setAttributeValue(ON_SUBMIT_VALIDATER_ATTR, formatter); } }
Часто возникает проблема: при использовании retainAM (сохранение состояния модуля приложения) мастер-деталь в табличных бинах не отражает текущего состояния данных. Для очищения датасетов во всех VO, связанных с AM, имеет смысл использовать методсодержимое колонки по центру (table)
am.clearVOCaches(null,Boolean.TRUE);
private void alignCenter(OAPageContext pageContext, OAWebBean webBean) { OATableBean versionTable = (OATableBean)webBean.findChildRecursive("SearchVO1"); versionTable.prepareForRendering(pageContext); DataObjectList columnFormats = (DataObjectList)versionTable.getColumnFormats(); DictionaryData columnFormat = null; // int childIndex = pageContext.findChildIndex(versionTable, "imgEdit"); columnFormat = (DictionaryData)columnFormats.getItem(childIndex); columnFormat.put(COLUMN_DATA_FORMAT_KEY, ICON_BUTTON_FORMAT); // childIndex = pageContext.findChildIndex(versionTable, "imgRemove"); columnFormat = (DictionaryData)columnFormats.getItem(childIndex); columnFormat.put(COLUMN_DATA_FORMAT_KEY, ICON_BUTTON_FORMAT); }