ERP 2.50:Developers Guide/Examples/Search/it
Languages: |
English | Italiano | Translate this article... |
Contents |
Introduzione
Questo esempio spiega gli elementi più importanti da tenere in considerazione quando si sviluppa un nuovo Riferimento di Ricerca.
E' possibile installare dal Repository Centrale il codice di questo esempio come un modulo e come template (Bank Account Search eBank Account Search Template).
Il codice per entrambi è disponibile anche su forge: link modulo e link template.
Obiettivo
La nostra azienda lavora con un numero considerevole di conti bancari. Visto che Openbravo ERP core non ha una Ricerca Conti Bancari, nella scheda Financial Management || Receivables & Payables || Transactions || Bank Statement || Header il campo Conto Bancario è visualizzato come una combo dove è difficile selezionare il valore desiderato.
Per risolvere questo problema andiamo a creare una form di Ricerca Conti Bancari che verrà richiamata da quel campo e ci permetterà di selezionare il conto bancario con alcuni criteri di ricerca.
Definizione Modulo
I nuovi componenti dovrebbero essere creati sempre all'interno di moduli. In questo caso creeremo un modulo per la Ricerca, e per modificare il core per usare questa nuova ricerca in Financial Management || Receivables & Payables || Transactions || Bank Statement || Header creerenmo anche un template con questa modifica del core.
Implementazione
Riferimenti Ricerca sono definiti nell' Application Dictionary ma la loro interfaccia utente viene implementata manualmente. Questo significa che il codice che mostra la UI non è generato automaticatimante ma manualmente.
Application Dictionary
Definizione di un Riferimento di tipo Ricerca
- I Riferimenti di tipo Ricerca sono definiti nella finestra Application Dictionary || Riferimenti con campo Tipo Validazione uguale a Validazione Ricerca. Non dimenticare di associare questo nuovo record ad un modulo.
- Nella scheda Application Dictionary || Reference || Reference >> Riferimento Selettore sono impostate la tabella e la colonna su cui la ricerca verrà utilizzata. In questo caso C_BankAccount e C_BankAccount_ID.
- Le Ricerche possono ricevere e restituire diverse variabili, definite nella scheda Application Dictionary || Reference || Reference >> Selector Reference >> Colonne del Riferimento Selettore , le variabili di input hanno come tipo In, Nome colonna DB è il nome della variabile in sessione. Una ricerca restituisce sempre almeno la chiave primaria del record selezionato, ma può ance restituire più valori , per definire i quali è possibile creare nuovi records in Colonne del Riferimento Selettore impostando il tipo a Out. In questo esempio la sola colonna in input è AD_Org_ID che verrà utilizzata per conoscere quale è il dato che verrà mostrato.
- Finalmente è definita la classe Java che implementa la Ricerca (org.openbravo.examples.search.bankAccount.BankAccount) e il mapping da invocare (/org.openbravo.examples.search.bankAccount/BankAccount.html).
Usare la Ricerca
Una volta che la ricerca è definita nell'Application Dicitionary, può essere associata alle colonne dove andrà utilizzata . Se vi sono nuove colonne in un modulo non va fatto nulla di speciale, per questo esempio cambieremo il comportamento standard di una colonna del core , in questo caso è necessario creare un modulo template che conterrà questa modifica al core.
Cambiare il riferimento nella colonna C_BankStatement.C_Bank_ID da TableDir a Search e selezionare la nuova Ricerca nel campo Reference Key Search.
Implementazione Manuale
Come le ricerche sono implementate manualmente esse possono costruite virtualmente in altri modi . Ad esempio sarebbe possibile creare una ricerca grafica per i Prodotti mostrando una albero per le categorie prodotto e i prodotti . Le ricerche standard consistono in una sezione filtro dove è definito il criterio per trovare i dati e una griglia dove i dati vengono mostrati e selezionati . Questo esempio implementa un caso standard.
Le ricerche sono disegnate per essere invocate da un campo. Ci sono due modi di invocare una Ricerca :
- Scrivendo alcuni dati nel campo e cliccando sulla chiave enter. In tal caso prende i dati nel campo come valore da cercare e se c'è un solo record che soddisfa questa condizione la pop-up di ricerca viene automaticatamente chiusa selezionando quel record. In questo esempio questo valore verrà controllato con il CodeAccount. Il Command passato alla servlet è KEY.
- Cliccando sul pulsante a destra del campo. In questo caso il valore viene cercato nell'identificatore di colonna, e la Ricerca rimane aperta anche se un solo record soddisfa i criteri di ricerca. Il Command passato alla servlet è DEFAULT.
Java
Metodo doPost
Comando KEY
if (vars.commandIn("KEY")) { String strKeyValue = vars.getRequestGlobalVariable("inpNameValue", "BankAccount.key"); final String strIDValue = vars.getStringParameter("inpIDValue"); final String strOrg = vars.getStringParameter("inpAD_Org_ID"); if (!strIDValue.equals("")) { final String strNameAux = BankAccountData.existsActualValue(this, strKeyValue, strIDValue); if (!strNameAux.equals("")) strKeyValue = strNameAux; } vars.removeSessionValue("BankAccount.name"); if (!strKeyValue.equals("")) vars.setSessionValue("BankAccount.key", strKeyValue + "%"); final BankAccountData[] data = BankAccountData.selectKey(this, vars.getLanguage(), Utility .getContext(this, vars, "#User_Client", "BankAccount"), Utility.getSelectorOrgs(this, vars, strOrg), strKeyValue + "%"); if (data != null && data.length == 1) { printPageKey(response, vars, data); } else printPage(response, vars, strKeyValue + "%", "", "paramKey"); }
Questo pezzo di codice viene eseguito quando viene premuta la chiave enter nel campo associato, riceve in strKeyValue il valore in quel campo e controlla se vi sono records che corrispondo a questo valore (data = BankAccountData.selectKey), se c'è un solo record chiama il metodo printPageKey che seleziona semplicemente quel valore nel campo e chiude la Ricerca se ci sono più records chiama il metodo printPage che mostrerà tutti i records.
La variabile strOrg riceve l' Organizzazione nel record corrente e viene utilizzato per ottenere la lista delle organizzazioni che possono essere riferite a quelle che verrano usate da Utility.getSelectorOrgs(this, vars, strOrg) per la query SQL.
Comando DEFAULT
if (vars.commandIn("DEFAULT")) { clearSessionValue(vars); String strNameValue = vars.getRequestGlobalVariable("inpNameValue", "BankAccount.name"); final String strIDValue = vars.getStringParameter("inpIDValue"); final String strKeyValue = vars.getGlobalVariable("inpKey", "BankAccount.key", ""); if (!strIDValue.equals("")) { final String strNameAux = BankAccountData.existsActual(this, vars.getLanguage(), strNameValue, strIDValue); if (!strNameAux.equals("")) strNameValue = strNameAux; } vars.removeSessionValue("BankAccount.key"); if (!strNameValue.equals("")) vars.setSessionValue("BusinessPartner.name", strNameValue + "%"); printPage(response, vars, strKeyValue, strNameValue.concat("%"), "paramName"); }
Questo codice viene eseguito quando viene premuto il pulsante vicino al campo. Controlla solo se vi sono records che corrispondono ai criteri (ora è controllato dall'identificatore di colonna) e chiama in ogni caso il metodo printPage che mostrerà tutti gli elementi corrispondenti e lascerà aperta la Ricerca.
Comandi di Griglia Ajax : STRUCTURE and DATA
Questi due comandi sono chiamati con Ajax per visualizzare la griglia con i dati. Il comando STRUCTURE chiama solo il metodo printGridStructure che stampa la struttura XML per la griglia , mentre DATA riceve tutti i filtri e chiama il metodo printGridData che recupera i dati e stampa tutti i record che soddisfano i criteri.
Metodo printPage
void printPage(HttpServletResponse response, VariablesSecureApp vars, String strKeyValue, String strNameValue, String focusedId) throws IOException, ServletException { final XmlDocument xmlDocument = xmlEngine.readXmlTemplate( "org/openbravo/examples/search/bankAccount/BankAccount").createXmlDocument(); //... some more code... try { ComboTableData comboTableData = new ComboTableData(vars, this, "TABLEDIR", "C_Bank_ID", "", "C_Bank", Utility.getContext(this, vars, "#AccessibleOrgTree", "BankAccount"), Utility .getContext(this, vars, "#User_Client", "BankAccount"), 0); Utility.fillSQLParameters(this, vars, null, comboTableData, "C_Bank", ""); xmlDocument.setData("reportBank_ID", "liststructure", comboTableData.select(false)); comboTableData = null; } catch (Exception ex) { throw new ServletException(ex); } xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); //...some more code: set all parameters for filter... response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); }
Questo metodo è utilizzato per visualizzare la sezione del filtro, riceve solo i valori scelti per i campi filtro e li visualizza. Si noti che quando la pagina HTML viene stampata chiamerà con ajax i metodi per stampare la griglia di filtraggio con i valori che ha ricevuto in questi campi.
In questo caso c'è una combo per le banche per selezionarle come filtro, è popolata tramite un oggetto ComboTableData, il più importante fra cui pensare è il filtro per le organizzazioni. Qui si è usato la variabile di sessione #AccessibleOrgTree che contiene la lista completa di tutte le organizzazioni accessibili dal ruolo attuale.
Metodo printPageKey
Si chiama quando vi è un singolo record che soddisfa i criteri di selezione nel comando KEY. Esso mostra solo una funzione javascript che contiene la la riga selezionata e chiude il pop-up. Si utilizza un modello di base comune al posto di uno definito all'interno del modulo corrente : org/openbravo/erpCommon/info/SearchUniqueKeyResponse che riceve solo un parametro script . Questo parametro è generato dal metodo generateResult:
String generateResult(BankAccountData[] data) throws IOException, ServletException { final StringBuffer html = new StringBuffer(); html.append("\nfunction validateSelector() {\n"); html.append("var key = \"" + data[0].cBankaccountId + "\";\n"); html.append("var text = \"" + Replace.replace(data[0].name, "\"", "\\\"") + "\";\n"); html.append("var parameter = new Array();\n"); html.append("parent.opener.closeSearch(\"SAVE\", key, text, parameter);\n"); html.append("}\n"); return html.toString(); }
Nella variabile KEY è memorizzata la chiave primaria della riga selezionata, mentre nella variabile testo vi è il testo da visualizzare nel campo.
Metodo printGridStructure
Mostra la struttura per la griglia (che colonne ha, qual'è la chiave ...), utilizza anche un modello comune:
org/openbravo/erpCommon/utility/DataGridStructure, dove il parametro più importante èstructure1, che riceve un oggetto SQLReturnObject[]. E il secondo parametro backendPageSize è quello di visualizzare il numero di record da visualizzare in un unica pagina. Definisce il numero di righe in TableSQLData.maxRowsPerGridPage
final XmlDocument xmlDocument = xmlEngine.readXmlTemplate( "org/openbravo/erpCommon/utility/DataGridStructure").createXmlDocument(); final SQLReturnObject[] data = getHeaders(vars); xmlDocument.setData("structure1", data); xmlDocument.setParameter("backendPageSize",String.valueOf(TableSQLData.maxRowsPerGridPage));
this object is obtained by getHeaders method which is listed bellow.
private static final String[] colNames = { "name", "value", "bank", "rowkey" }; private SQLReturnObject[] getHeaders(VariablesSecureApp vars) { SQLReturnObject[] data = null; final Vector<SQLReturnObject> vAux = new Vector<SQLReturnObject>(); final String[] colWidths = { "400", "200", "200", "0" }; for (int i = 0; i < colNames.length; i++) { final SQLReturnObject dataAux = new SQLReturnObject(); // set all paramters for the SQLReturnObject ... // ... final String name = Utility.messageBD(this, "BNKACTS_" + colNames[i].toUpperCase(), vars .getLanguage()); dataAux.setData("name", (name.startsWith("BNKACTS_") ? colNames[i] : name)); dataAux.setData("type", "string"); dataAux.setData("width", colWidths[i]); vAux.addElement(dataAux); } data = new SQLReturnObject[vAux.size()]; vAux.copyInto(data); return data; }
Questo metodo crea un String [] in colNames con tutte le colonne che la griglia avrà. Si noti che questi nomi devono corrispondere con i nomi del FieldProvider quando si recuperano i dati. colWidths''è un altro array con la stessa lunghezza che indica la dimensione per ogni colonna definita in colNames.
Poi un SQLReturnObject viene creato per ogni colonna, qui la parte più interessante è come queste colonne vengono intestate, è fatto con la proprietà "name", calcolata utilizzando un messaggio definito nel database, tali messaggi devono essere definiti all'interno del modulo corrente.
La colonna rowkey conterrà l'ID e il testo da visualizzare nel campo nel caso in cui sia selezionata la riga.
Metodo printGridData
Questo è il metodo che recupera e visualizza tutti i dati nella griglia.
void printGridData(HttpServletResponse response, VariablesSecureApp vars, String strKey, String strName, String strOrg, String strBankId, String strOrderCols, String strOrderDirs, String strOffset, String strPageSize, String strNewFilter) throws IOException, ServletException { int page = 0; final SQLReturnObject[] headers = getHeaders(vars); if (headers != null) { try { // build sql orderBy clause String strOrderBy = SelectorUtility.buildOrderByClause(strOrderCols, strOrderDirs); page = TableSQLData.calcAndGetBackendPage(vars, "BankAccount.currentPage"); if (vars.getStringParameter("movePage", "").length() > 0) { // on movePage action force executing countRows again strNewFilter = ""; } int oldOffset = offset; offset = (page * TableSQLData.maxRowsPerGridPage) + offset; log4j.debug("relativeOffset: " + oldOffset + " absoluteOffset: " + offset); // New filter or first load if (strNewFilter.equals("1") || strNewFilter.equals("")) { String rownum = "0", oraLimit1 = null, oraLimit2 = null, pgLimit = null; if (this.myPool.getRDBMS().equalsIgnoreCase("ORACLE")) { oraLimit1 = String.valueOf(offset + TableSQLData.maxRowsPerGridPage); oraLimit2 = (offset + 1) + " AND " + oraLimit1; rownum = "ROWNUM"; } else { pgLimit = TableSQLData.maxRowsPerGridPage + " OFFSET " + offset; } strNumRows = BankAccountData.countRows(this,rownum, Utility.getContext(this, vars, "#User_Client", "BankAccount"), Utility.getSelectorOrgs(this, vars, strOrg), strKey, strName, strBankId,pgLimit, oraLimit1, oraLimit2); vars.setSessionValue("BankAccount.numrows", strNumRows); } else { strNumRows = vars.getSessionValue("BankAccount.numrows"); } // Filtering result if (this.myPool.getRDBMS().equalsIgnoreCase("ORACLE")) { final String oraLimit = (Integer.parseInt(strOffset) + 1) + " AND " + (Integer.parseInt(strOffset) + Integer.parseInt(strPageSize)); data = BankAccountData.select(this, "ROWNUM", vars.getLanguage(), Utility.getContext( this, vars, "#User_Client", "BankAccount"), Utility.getSelectorOrgs(this, vars, strOrg), strKey, strName, strBankId, strOrderBy, oraLimit, ""); } else { final String pgLimit = strPageSize + " OFFSET " + strOffset; data = BankAccountData.select(this, "1", vars.getLanguage(), Utility.getContext(this, vars, "#User_Client", "BankAccount"), Utility.getSelectorOrgs(this, vars, strOrg), strKey, strName, strBankId, strOrderBy, "", pgLimit); } } catch (Exception e) { // ... some code here } } StringBuffer strRowsData = new StringBuffer(); // ... populate rowsData with the xml structure response.setContentType("text/xml; charset=UTF-8"); response.setHeader("Cache-Control", "no-cache"); final PrintWriter out = response.getWriter(); if (log4j.isDebugEnabled()) log4j.debug(strRowsData.toString()); out.print(strRowsData.toString()); out.close(); }
In primo luogo si calcola il numero totale di righe che corrisponde ai criteri ed è memorizzato nella variabile strNumRows, si noti che esso deve essere calcolato a parte i dati reali in quanto ha un offset e un limite che può ridurre la quantità di record.
Dopo che è stato calcolato il limite di record che verrà applicato, questo è fatto con un codice specifico di database, quindi è necessario sapere se il database corrente è Oracle o PostgreSQL.
E infine, i dati sono popolati con il risultato della query: data =BankAccountData.select.
Dopo che una struttura XML per i dati viene generata in rowsData ed è direttamente stampata. La struttura XML deve apparire così:
<xml-data> <status> <type><![CDATA[Hidden]]></type> <title><![CDATA[]]></title> <description><![CDATA[]]></description> </status> <rows numRows="1" backendPage="5"> <tr> <td><![CDATA[Uncle Scroogre Bank - Uncle Scroogre Bank. 0000-0000-00-0000000000]]></td> <td><![CDATA[0000000000]]></td> <td><![CDATA[Uncle Scroogre Bank]]></td> <td><![CDATA[1000000#Uncle Scroogre Bank - Uncle Scroogre Bank. 0000-0000-00-0000000000]]></td> </tr> </rows> </xml-data>
Se un selettore che può essere usato per selezionare più record in una sola volta deve essere convertito un cambio supplementare è necessario per il suo codice java. Il selettore multiplo dispone di un ulteriore metodo nelle sue servlet che è chiamata per ottenere l'elenco di ID all'interno di una specifica offset-range di record. Questo offset-range di record esige di essere convertito dal relativo offset lato client al offset assoluto lato server (semplicemente aggiungendo backendPageSize + backendPage).
private void printGridDataSelectedRows(HttpServletResponse response, VariablesSecureApp vars, String strKey, String strName, String strProductCategory, String strOrg, String strOrderCols, String strOrderDirs) throws IOException, ServletException { int minOffset = Integer.parseInt(vars.getStringParameter("minOffset")); int maxOffset = Integer.parseInt(vars.getStringParameter("maxOffset")); log4j.debug("Output: print page ids, minOffset: " + minOffset + ", maxOffset: " + maxOffset); String type = "Hidden"; String title = ""; String description = ""; FieldProvider[] data = null; FieldProvider[] res = null; try { // build sql orderBy clause String strOrderBy = SelectorUtility.buildOrderByClause(strOrderCols, strOrderDirs); String strPage = vars.getSessionValue("BankAccount|currentPage", "0"); int page = Integer.parseInt(strPage); int oldMinOffset = minOffset; int oldMaxOffset = maxOffset; minOffset = (page * TableSQLData.maxRowsPerGridPage) + minOffset; maxOffset = (page * TableSQLData.maxRowsPerGridPage) + maxOffset; log4j.debug("relativeMinOffset: " + oldMinOffset + " absoluteMinOffset: " + minOffset); log4j.debug("relativeMaxOffset: " + oldMaxOffset + " absoluteMaxOffset: " + maxOffset); // Filtering result if (this.myPool.getRDBMS().equalsIgnoreCase("ORACLE")) { String oraLimit1 = String.valueOf(maxOffset); String oraLimit2 = (minOffset + 1) + " AND " + oraLimit1; data = BankAccountData.select(this, "ROWNUM", vars.getLanguage(), Utility.getContext( this, vars, "#User_Client", "BankAccount"), Utility.getSelectorOrgs(this, vars, strOrg), strKey, strName, strBankId, strOrderBy, oraLimit, ""); } else { // minOffset and maxOffset are zero based so pageSize is difference +1 int pageSize = maxOffset - minOffset + 1; String pgLimit = pageSize + " OFFSET " + minOffset; data = BankAccountData.select(this, "ROWNUM", vars.getLanguage(), Utility.getContext( this, vars, "#User_Client", "BankAccount"), Utility.getSelectorOrgs(this, vars, strOrg), strKey, strName, strBankId, strOrderBy, oraLimit, ""); } // result field has to be named id -> rename by copy the list res = new FieldProvider[data.length]; for (int i = 0; i < data.length; i++) { SQLReturnObject sqlReturnObject = new SQLReturnObject(); sqlReturnObject.setData("id", data[i].getField("rowkey")); res[i] = sqlReturnObject; } } catch (Exception e) { log4j.error("Error obtaining id-list for getIdsInRange", e); type = "Error"; title = "Error"; if (!e.getMessage().startsWith("<![CDATA[")) description = "<![CDATA[" + e.getMessage() + "]]>"; } XmlDocument xmlDocument = xmlEngine.readXmlTemplate( "org/openbravo/erpCommon/utility/DataGridID").createXmlDocument(); xmlDocument.setParameter("type", type); xmlDocument.setParameter("title", title); xmlDocument.setParameter("description", description); xmlDocument.setData("structure1", res); response.setContentType("text/xml; charset=UTF-8"); response.setHeader("Cache-Control", "no-cache"); PrintWriter out = response.getWriter(); log4j.debug(xmlDocument.print()); out.println(xmlDocument.print()); out.close(); }
XSQL
Il file XSQL non merita alcuna considerazione speciale, è solo necessario per attuare tutte le query utilizzate nelle sezioni precedenti, tenendo sempre in considerazione il filtro del client e della organizzazione. Un esempio xsql per il metodo countRows è indicato di seguito.
<SqlMethod name="countRows" type="preparedStatement" return="String"> <SqlMethodComment></SqlMethodComment> <Sql> <![CDATA[ SELECT COUNT(*) AS VALUE FROM ( SELECT '0' AS RN1, B.* FROM ( SELECT 1 FROM C_BankAccount B WHERE B.AD_CLIENT_ID IN ('1') AND B.AD_ORG_ID IN ('1') AND B.ISACTIVE = 'Y' AND 1=1 ) B ) A ]]></Sql> <Field name="position" value="count"/> <Parameter name="rownum" type="replace" optional="true" after="FROM ( SELECT " text="'0'" /> <Parameter name="language"/> <Parameter name="adUserClient" type="replace" optional="true" after="P.AD_CLIENT_ID IN (" text="'1'"/> <Parameter name="adUserOrg" type="replace" optional="true" after="P.AD_ORG_ID IN (" text="'1'"/> <Parameter name="key" ignoreValue="%" optional="true" after="AND P.ISACTIVE = 'Y'"><![CDATA[ AND UPPER(B.Value) LIKE UPPER(?) ]]></Parameter> <Parameter name="name" ignoreValue="%" optional="true" after="AND P.ISACTIVE = 'Y'"><![CDATA[ AND UPPER(B.Name) LIKE UPPER(?) ]]></Parameter> <Parameter name="pgLimit" type="argument" optional="true" after="AND 1=1"><![CDATA[LIMIT ]]></Parameter> <Parameter name="oraLimit1" type="argument" optional="true" after=") B"><![CDATA[ WHERE ROWNUM <= ]]></Parameter> <Parameter name="oraLimit2" type="argument" optional="true" after=") A "><![CDATA[WHERE RN1 BETWEEN ]]></Parameter> </SqlMethod>
HTML Template
Vediamo brevemente le sezioni più rilevanti nel modello HTML.
Javascript
function validateSelector(action) { var pos; var keys; var key; var text; var parameter; if(action == "SAVE") { pos = getSelectedPos(); keys = getSelectedValues().split("#"); key = keys[0]; text = keys[1]; parameter = new Array(); } parent.opener.closeSearch(action, key, text, parameter); }
Questa funzione viene utilizzata quando una riga è selezionata, prende il campo rowkey delle righe selezionate e lo divide per ottenere l'ID del record e il testo che verrà visualizzato nel campo che ha richiamato la ricerca, poi si chiude la pop-up.
function gridMovePage(direction) { dijit.byId('grid').gridMovePage(direction); return true; } function updateHeader(liveGrid, offset) { var backendPageSize = liveGrid.getBackendPageSize(); var currPageStart = (liveGrid.metaData.getBackendPage()*backendPageSize); var pageFull = (liveGrid.metaData.getTotalRows() >= backendPageSize); var firstPage = (liveGrid.metaData.getBackendPage() == 0); var res = "<nobr class='DataGrid_Popup_text_bookmark'>"; if (!firstPage) { res = res + "<a href='#' onclick='gridMovePage(\"PREVIOUSPAGE\"); setWindowElementFocus(\"grid_table_dummy_input\",\"id\");' class='DataGrid_Popup_text_pagerange' id='prevPage_link'>" + getMessage("GridPreviousPage") + " " + backendPageSize +"</a> | "; } res = res + ((liveGrid.visibleRows>0)?(currPageStart+offset+1):0) + " - "+ (currPageStart+offset+liveGrid.visibleRows) + " / " + (currPageStart+liveGrid.metaData.getTotalRows()); if (pageFull) { res = res + " | <a href='#' onclick='gridMovePage(\"NEXTPAGE\"); setWindowElementFocus(\"grid_table_dummy_input\",\"id\");' class='DataGrid_Popup_text_pagerange' id='nextPage_link'>" + getMessage("GridNextPage") + " " + backendPageSize +"</a>"; } res = res + "</nobr>"; liveGrid.setGridPaging(!firstPage,pageFull); dojo.byId('bookmark').innerHTML = res; }
Queste funzioni sono usate per l'impaginazione'in'Grid struture. Quando il pulsante Avanti viene cliccato si chiama la funzione'gridMovePage e le righe sono calcolati in base albackendPageSize .
Campi Filtro
La sezione filtro è composta da campi regolari che formeranno il filtro.
Pulsante Ricerca
<td class="Button_LeftAlign_ContentCell"> <div> <button type="button" id="buttonSearch" class="ButtonLink" onclick="setFilters();return false;" onfocus="buttonEvent('onfocus', this); window.status='Search'; return true;" onblur="buttonEvent('onblur', this);" onkeyup="buttonEvent('onkeyup', this);" onkeydown="buttonEvent('onkeydown', this);" onkeypress="buttonEvent('onkeypress', this);" onmouseup="buttonEvent('onmouseup', this);" onmousedown="buttonEvent('onmousedown', this);" onmouseover="buttonEvent('onmouseover', this); window.status='Search'; return true;" onmouseout="buttonEvent('onmouseout', this);"> <table class="Button"> <tr> <td class="Button_left"><img class="Button_Icon Button_Icon_search" alt="Search" title="Search" src="../../../../../web/images/blank.gif" border="0" /></td> <td class="Button_text Button_width">Search</td> <td class="Button_right"></td> </tr> </table> </button> </div> </td>
Si tratta di un normale pulsante che chiama il metodo setFilters() di searchs.js.
Data grid
<tr> <td> <div class="Popup_ContentPane_Client" style="overflow: hidden; height: 0px;" id="client_middle"> <table summary="" id="sectionDetail"> <tr> <td> <table cellspacing="0" cellpadding="0" width="10px" class="DataGrid_Header_Table DataGrid_Body_Table" style="table-layout: auto;" id="grid_sample"> <tr class="DataGrid_Body_Row" id="grid_sample_header"> <th width="10px" class="DataGrid_Header_Cell">DataGrid</th> </tr> <tr class="DataGrid_Body_Row DataGrid_Body_Row_1" onclick="" id="grid_sample_row"> <td class="DataGrid_Body_Cell">Loading...</td> </tr> </table> <table cellspacing="0" cellpadding="0" width="0px" height="0px" cellspacing="0" cellpadding="0"> <tr> <td><input type="text" class="DataGrid_Table_Dummy_Input" id="grid_table_dummy_input"></input></td> </tr> </table> <table width="100%" cellspacing="0" cellpadding="0" border="0" id="grid_bookmark"> <tr> <td class="DataGrid_Popup_text_container"> <div id="bookmark"> <nobr class='DataGrid_Popup_text_bookmark'> </nobr> </div> </td> </tr> </table> <table width="100%" cellspacing="0" cellpadding="0" border="0" class="Main_Client_TableRelation" id="grid_table"> <tr> <td> <div id="grid" dojotype="openbravo.widget.DataGrid" structureurl="../org.openbravo.examples.search.bankAccount/BankAccount.html?Command=STRUCTURE" dataurl="../org.openbravo.examples.search.bankAccount/BankAccount.html?Command=DATA" updatesurl="../org.openbravo.examples.search.bankAccount/BankAccount.html?Command=DATA" calculatenumrows="true" editable="false" sortable="true" deleteable="true" oninvalidvalue="alert" onscroll="updateHeader" ongridload="onGridLoadDo" buffersize="3.0" showlinenumbers="true" offset="0" sortcols="1" sortdirs="ASC" defaultrow="0" maxwidth="99%" percentagewidthrelativetoid="client_middle" multipleRowSelection="false" preventcache="true" usecache="true" cachecontent="false"> </div> </td> </tr> </table> </td> </tr> </table> </div> </td> </tr>
Questo pezzo di codice illustra la griglia di dati chiamando i metodi ajax per popolarla.
Pulsante OK
Sotto la griglia viene visualizzato un pulsante OK , è un pulsante standard che chiama il metodo validateSelector('SAVE') .
Risultato Finale
Il Risultato Finale per questa ricerca è simile a come segue .
Languages: |