Generallità delle WAM
Un Web Application Module:
E' un programma LANSA a tutti gli effetti
Supporta il full RDML/X nativo NON è "visuale"
Può essere eseguito SOLO dal WEB
Può essere "Standard" o per il "Framework"
E' composto da WEBROUTINE
WEBROUTINE
La WEBROUTINE e il pezzo di codice che viene eseguito quando si richiama il programma via WEB
Ad ogni WEBROUTINE corrisponde una pagina sul Browser
I dati da gestire nelle pagine vengono definiti tramite delle WEB_MAP
WEBMAP
Un Web Application Module:
E' un programma LANSA a tutti gli effetti
Supporta il full RDML/X nativo
NON è "visuale"
Può essere eseguito SOLO dal WEB
Può essere "Standard" o per il "Framework"
E' composto da WEBROUTINE
La WEBROUTINE e il pezzo di codice che viene eseguito quando si richiama il programma via WEB
Ad ogni WEBROUTINE corrisponde una pagina sul Browser
I dati da gestire nelle pagine vengono definiti tramite delle WEB_MAP
Per capire come funzionano le WEB_MAP bisogna prima capire come viene generata una pagina HTML e gestiti i Moduli HTML.
Un Modulo HTML è composto da una serie di elementi (caselle di testo, check-box, radio-button, combp-box) che danno la possibilità
di passare una serie di dati al server nel formato nome=valore.
IL modulo è delimitato dai tag <FORM></FORM>
GLi elementi sono composti dal tag <INPUT> che in base all'attributo type determina il tipo di elemento:
- HIDDEN Crea un elemento che ha un nome ed un valore ma non è visibile nella pagina
- TEXT Crea una casella di testo standard per inputare valori
- PASSWORD Crea una casella di testo che non visualizza ciò che viene scritto
- CHECKBOX Crea una casella di spunta
- RADIO Crea una radio-button di selezione
- BUTTON Crea un pulsante
- RESET Crea il pulsante che per default cancella tutti i valori del Modulo
- SUBMIT Crea il pulsante che per default invia i dati al server
- FILE Crea una casella di scelta di file locali per eseguire l'upload sul server
Ogni WEBROUTINE (che corrisponde ad una pagina HTML) ha al suo interno un Modulo di nome "LANSA"
E' IMPORTANTE capire che :
se all'interno del Modulo (FORM) esiste il tag <INPUT> allora il valore verrà passato;
se all'interno del Modulo (FORM) il valore viene presentato come testo semplice NON verrà passato alcun valore.
Alla luce di quanto detto analizziamo il comando WEB_MAP
Questo comando dice alla WEBROUTINE i campi che si vogliono gestire come flusso dati, ovvero quello che riceve e quello che restituisce (come output sulla pagina).
La WEB_MAP ha un "verso" (parametro FOR) che dal punto di vista della WEBROUTINE può essere:
- *INPUT : la WEBROUTINE RICEVE IL FLUSSO
- *OUTPUT : la WEBROUTINE RESTITUISCE IL FLUSSO
- *BOTH : il FLUSSO viaggia in ENTRAMBI I SENSI
Nel parametro FIELDS() vengono effettivamente indicati i campi gestiti; ogni campo può avere un attributo che può essere (E NON CENTRA NULLA CON IL VERSO) :
- *INPUT : il campo può essere modificato
- *OUTPUT : il campo viene SOLO visualizzato
- *HIDDEN : il campo c'è ma non si vede
Se non viene specificato nessun attributo viene preso per dafault *INPUT
E' possibile utilizzare più comandi WEB_MAP all'interno del programma, basta che un campo sia presente una volta sola all'interno delle stesso SCOPE.
Le WEB_MAP hanno un loro SCOPE ovvero:
se definite in testa al programma (al di fuori cioè delle WEBROUTINE), i campi saranno mappati per TUTTE le WEBROUTINE
se definite all'interno di una WEBROUTINE hanno valenza solo per quella:
Come si trasforma tutto questo in HTML ?
I campi presenti nelle WEB_MAP con verso *INPUT non verranno in alcum modo generati all'interno del Modulo (FORM) della pagina HTML, quindi la
WEBROUTINE riceverà i valori o come parametri durante la chiamata o da altre WEBROUTINE
I campi presenti nelle WEB_MAP con verso *OUTPUT o *BOTH verrano generati nella pagina HTML nel modo seguente:
quelli con attributo *INPUT diventeranno dei tag <INPUT type="TEXT" name="Nome del campo" value="Valore del Campo"/>
quelli con attributo *HIDDEN diventeranno dei tag <INPUT type="HIDDEN" name="Nome del campo" value="Valore del Campo"/>
quelli con attributo *OUTPUT deventeranno del semplice testo.
Da questo salta all'occhio che I CAMPI IN *OUTPUT NON VERRANO MAI RIPASSATI ANCHE SE SI TROVANO IN UNA WEB_MAP PER *INPUT O *BOTH
ESEMPIO di WEB_MAP
WEBROUTINE Name(Prova)
WEB_MAP FOR(*INPUT) FIELDS(#CAMPO1)
WEB_MAP FOR(*OUTPUT) FIELDS(#CAMPO2)
WEB_MAP FOR(*BOTH) FIELDS(#CAMPO3 (#CAMPO4 *OUTPUT) (#CAMPO5 *HIDDEN))
....
ENDROUTINE
#CAMPO1 viene ricevuto dalla routine
#CAMPO2 viene visualizzato nella pagina ed è modificabile ma non verrà ripassato alla routine quando richiamata
#CAMPO3 viene visualizzato, è modificabile ed è ripassato
#CAMPO4 viene visualizzato, NON è modificabile e NON è ripassato
#CAMPO5 NON viene visualizzato ma viene ripassato
***** ATTENZIONE *****
E' POSSIBILE INSERIRE LO STESSO CAMPO IN WEB_MAP DI DIFFERENTI WEBROUTINE (PERCHE' HANNO SCOPE DIFFERENTI),
PER QUESTO BISOGNA FARE ATTENZIONE AI CASI PARTICOLARI IN CUI EFFETTIVAMENTE IL CAMPO DEVE ESSERE PASSATO
TRA WAM/WEBROUTINE DIFFERENTI
WAM PER IL FRAMEWORK (FILTRI E COMMAND)
WAM STANDARD (POP UP)
REGOLE GENERALI DI PROGRAMMAZIONE WEB
Per il confronto delle impostazioni tabellari all'interno dei programmi NON utilizzare più le variabili *MTXTVAR001/2/3/4 ma confrontantare direttamente con "S" / "N" / "SI" / "NO"
I programmi RDML/X devono fare le CALL ad altri programmi specificando come processo *DIRECT. ATTENZIONE ad eventuali CALL fatte all'interno dei programmi chiamati. IMPORTANTE NOTARE CHE TUTTI I PROCESSI COINVOLTI IN CALL DA PROGRAMMI RDML/X DEVONO ESSERE SAA/CUA
I campi Ditta/Deposito devono essere inizializzati in questa maniera e passati in SUBMIT o con EXCHANGE:
£R_IDCDAZ := £DMWAMHND.up_DatiSessione.up_Azienda
£R_IDDAZ := £DMWAMHND.up_DatiSessione.up_DescrAzienda
£R_IDCDEP := £DMWAMHND.up_DatiSessione.up_Deposito
£R_IDDDEP := £DMWAMHND.up_DatiSessione.up_DescrDeposito
£R_IDMLDEP := £DMWAMHND.up_DatiSessione.up_MultiDeposito
£R_USRJOBQ := *EDUSRJOBQ
La submit va formattata in questa maniera:
SUBMIT PROCESS(<Processo>) FUNCTION(<Funzione>) EXCHANGE(<Campi: tra cui quelli sopra>) JOBD(*USRPRF) JOBQ(£R_USRJOBQ) OUTQ(*CURRENT)
ATT.NE: se il programma chiamato da SUBMIT e/o CALL chiama a sua volta altri programmi, occorre verificare il corretto passaggio fino alla fine dei suddetti campi, che altrimenti verrebbero impostati al valore di default, e cioè NULLO, per le esecuzioni da web.
Quando è necessario passare l'utente a funzioni batch utilizzare la seguente sintassi:
<Campo Utente utilizzato> := £ThisHandler.avLoggedonUser / £ThisFilter.avLoggedonuser
Tutti i messaggi di errore devono essere dettagliati in quanto non c'è più la visualizzazione in viola dei campi a cui l'errore fa riferimento.
Fare riferimento ai messaggi numero ED01807, ED02103, ED02221, ED03013, ED03014, ED03078 ecc.
Utilizzare i "Gestori delle Tabelle" per la lettura delle impostazioni.
Ottimizzare le SELECT indentate cercando di convertirle in SELECT_SQL
Ottimizzare le UPDATE facendo in modo di aggiornare SOLAMENTE i campi GESTITI dal PROGRAMMA
E' bene informare l'utente sulle attuali impostazioni della procedura e notificare messaggi di avviso (tipo "Prezzo preso dall'anagrafico" oppure "Prezzo scaduto") in uno dei seguenti modi:
Se il numero dei messaggi è fisso (ovvero esiste un campo per ogni messaggio), inserire i campi (in OUTPUT) all'interno di un <fieldset> con <legend> "Informazioni" (Utilizzare lo stile grassetto per i campi)
Se il numero dei messaggi è variabile, utilizzare la fast-part memo all'interno di un <fieldset> con <legend> "Informazioni"
Utilizzare la Fast-Part Memo nel caso sia necessario ricevere dei Barcodes multipli
Quando utilizzare le BIF TRANSFORM_LIST o UD_TRANSFORM_LIST:
USE TRANSFORM_LIST:
- NON OK x creazione file in formato DBF
UD_TRANSFORM_LIST:
- OK x creazione file in formato DBF (format type=3)
- NON sempre disponibile comando inverso x UD_TRANSFORM_FILE
Gestione Lock. Attenersi al documento relativo
Gestione Stampe. Attenersi al documento relativo(*** DA RIVEDERE CON SILVIA ***)
DISEGNO DELLA PAGINA XSL
formattare la visualizzazione delle taglie(c'è un documento di Stefano Foresi).
ed_display_img per visualizzazione immagini.
descrivere metodo da utlizzare per mettere le descrizioni vicino ai codice per il ritorno automatico dalla pop-up
spiegare la differenza tra <xsl:if> e style="display: xxxx"
STRUTTURA
FUNCTION OPTIONS(*DIRECT)
BEGIN_COM ROLE(*EXTENDS £PRIM_WAM) LAYOUTWEBLET('vlf_layout')
LE DICHIARAZIONI SOTTO SI ESCLUDONO A VICENDA
* ===================================================================================
* Standard declares for a filter
DEFINE_COM CLASS(£VF_SW100) NAME(£avFrameworkManager)
DEFINE_COM CLASS(£VF_AW007) NAME(£ThisFilter) REFERENCE(*Dynamic)
DEFINE_COM CLASS(£VF_LW002) NAME(£avListManager) REFERENCE(*Dynamic)
DEFINE_COM CLASS(£FP_IN001) NAME(£FastPart) REFERENCE(*Dynamic)
* Standard declares for a command-handler
DEFINE_COM CLASS(£VF_SW100) NAME(£avFrameworkManager)
DEFINE_COM CLASS(£vf_AW010) NAME(£ThisHandler) REFERENCE(*Dynamic)
DEFINE_COM CLASS(£VF_LW002) NAME(£avListManager) REFERENCE(*Dynamic)
DEFINE_COM CLASS(£FP_IN001) NAME(£FastPart) REFERENCE(*Dynamic)
* ===================================================================================
* OGGETTO DMWAMHND - SERVE PER ARCHITTETTURA INTERNA EMMEDATA
DEFINE_COM CLASS(£DMWAMHND) NAME(£DMWAMHND)
* VL Framework map fields. DO NOT CHANGE.
WEB_MAP FOR(*BOTH) FIELDS((£VF_FRAMEI *PRIVATE) (£VF_FRAMEW *PRIVATE) (£VF_FRAMES *PRIVATE) (£VF_ELXTOF *PRIVATE) (£VF_ELXN01 *PRIVATE) (£VF_ELXN02 *PRIVATE) (£VF_ELXN03 *PRIVATE) (£VF_ELXN04 *PRIVATE) (£VF_ELXN05 *PRIVATE) (£VF_ELXN06 *PRIVATE) (£VF_ELXN07 *PRIVATE) (£VF_ELXN08 *PRIVATE) (£VF_ELXN09 *PRIVATE) (£VF_ELXN10 *PRIVATE) (£VF_ELXA01 *PRIVATE) (£VF_ELXA02 *PRIVATE) (£VF_ELXA03 *PRIVATE) (£VF_ELXA04 *PRIVATE) (£VF_ELXA05 *PRIVATE) (£VF_ELXA06 *PRIVATE) (£VF_ELXA07 *PRIVATE) (£VF_ELXA08 *PRIVATE) (£VF_ELXA09 *PRIVATE) (£VF_ELXA10 *PRIVATE))
* Map fields used in this WAM.
WEB_MAP FOR(*BOTH) FIELDS(<CAMPO1> <CAMPO2> <CAMPOn>)
* ===================================================================================
* Standard webroutine used by all VLF WAM filters and command handlers. DO NOT CHANGE the Web routine name.
* ===================================================================================
WEBROUTINE NAME(UHandleEvent)
* REGISTRAZIONE DEGLI EVENTI GESTITI
INVOKE METHOD(£avFrameworkManager.avRegisterEvent) NAMED(<NOME EVENTO>) SIGNALASWAMEVENT(<Numero Evento associato (da 1 a 20)>)
* Standard WAM initialisation.
INVOKE METHOD(£avFrameworkManager.avInitializeWAM) TYPE(FILTER) INVOKER(£com_owner) LISTMANAGER(£avListManager) FILTERMANAGER(£ThisFilter) FASTPARTMANAGER(£FastPart)
INVOKE METHOD(£avFrameworkManager.avHandleWAMEvent) ANCHORBLOCK(£vf_framew) EVENT(£vf_event) DESIGNMODE(£vf_framed) SKIN(£VF_Frames) METATAG(£vf_elmeta) TOF(£vf_elxtof) N01(£vf_elxn01) N02(£vf_elxn02) N03(£vf_elxn03) N04(£vf_elxn04) N05(£vf_elxn05) N06(£vf_elxn06) N07(£vf_elxn07) N08(£vf_elxn08) N09(£vf_elxn09) N10(£vf_elxn10) A01(£vf_elxA01) A02(£vf_elxA02) A03(£vf_elxA03) A04(£vf_elxA04) A05(£vf_elxA05) A06(£vf_elxA06) A07(£vf_elxA07) A08(£vf_elxA08) A09(£vf_elxA09) A10(£vf_elxA10) SSINAME(£VF_FRAMEI)
ENDROUTINE
* ===================================================================================
* Punto di ingresso. VIENE ESEGUITA COME PRIMA ROUTINE AD OGNI ESECUZIONE DELLA WAM. (!!SEMPRE!!)
* ===================================================================================
EVTROUTINE HANDLING(£avFrameworkManager.uInitialize) OPTIONS(*NOCLEARMESSAGES *NOCLEARERRORS)
* Metodo implementato da EMMEDATA per il funzionamento all'interno dell'architettura
£DMWAMHND.um_InitializeWAM FRAMEWORKMANAGER(£avFrameWorkManager) TIPO(<"FILTER" o "COMMAND">) LISTMANAGER(£avListManager) HANDLERMANAGER(<£ThisFilter o £ThisHandler>) FASTPARTMANAGER(£FastPart)
* Operazioni da implementate in questo punto:
* - lettura dell'instance-list (se necessario)
* - lettura dei campi utilizzati sempre nelle elaborazioni per evitare di passarli tramite la WEB_MAP
* (a meno che non debbano essere presenti a video)
ENDROUTINE
* ===================================================================================
* ROUTINE che viene eseguita SOLO LA PRIMA VOLTA e dopo "uInitialize"
* ===================================================================================
EVTROUTINE HANDLING(£avFrameworkManager.uExecute) OPTIONS(*NOCLEARMESSAGES *NOCLEARERRORS)
* Metodo implementato da EMMEDATA per il funzionamento all'interno dell'architettura
£DMWAMHND.um_ExecuteWAM FRAMEWORKMANAGER(£avFrameWorkManager) TIPO(<"FILTER" o "COMMAND">) LISTMANAGER(£avListManager) HANDLERMANAGER(<£ThisFilter o £ThisHandler>) FASTPARTMANAGER(£FastPart)
* FORMATTAZIONE DEI BOTTONI
£DMWAMHND.up_ButtonHandler.um_STDButton PITEMBOTTONE(<n>) PGESTITO(TRUE)
* Operazioni da implementate in questo punto:
* - elaborazioni che devono essere eseguite solo la prima volta (impostazione della videata)
* - formattazione di eventuali Fast-Part
ENDROUTINE
* ===================================================================================
* ROUTINE che viene eseguita SEMPRE AL TERMINE DEL PROGRAMMA
* ===================================================================================
EVTROUTINE HANDLING(£avFrameworkManager.uTerminate) OPTIONS(*NOCLEARMESSAGES *NOCLEARERRORS)
* Metodo implementato da EMMEDATA per il funzionamento all'interno dell'architettura
£DMWAMHND.um_TerminateWAM FRAMEWORKMANAGER(£avFrameWorkManager) TIPO(<"FILTER" o "COMMAND">) LISTMANAGER(£avListManager) HANDLERMANAGER(<£ThisFilter o £ThisHandler>) FASTPARTMANAGER(£FastPart)
* Operazioni da implementate in questo punto:
* - decodifica delle descrizioni a video
ENDROUTINE
* ===================================================================================
* ROUTINE GESTIONE EVENTI
* ===================================================================================
EVTROUTINE HANDLING(£avFrameworkManager.uWAMEvent_<n>) OPTIONS(*NOCLEARMESSAGES *NOCLEARERRORS)
* Codifica
ENDROUTINE
END_COM
Riepilogo:
Ha una sola WEBROUTINE chiamata "uHandleEvent"
Ha una WEB_MAP globale con tutti i campi base del FrameWork (fissa)
Può avere una o più WEB_MAP globali con i campi da utilizzare nel programma (opzionale)
Ha tre EVTROUTINE principali eseguite con questa sequenza:
-uInitialize (sempre)
-uExecute (solo la prima volta)
-uTerminate (sempre)
Ha a disposizione 20 routine (uWAMEvent_<n>) associabili ad eventi gestiti dal programmatore alle quali è possibile passare dei parametri per gestire più eventi logici con la stessa routine fisica.
TASTI STANDARD E TASTI FUNZIONE
La regola generale è che tutti i tasti attivi all'interno di una WAM devono essere visibili: quindi vanno eventualmente disabilitati.
I Tasti Standard sono gestiti con la Fast-Part FP_RBTSTD.
Ogni bottone è associato ad un id fisso come da schema seguente:
1 Salva
2 Modifica
3 Cerca
4 Elimina
5 Annulla
6 Chiudi
7 Stampa
8 Aggiorna
9 Conferma
10 Decodifica
11 Forza
si devono abilitare nella routine uExecute solo quelli necessari tramite l'istruzione:
£DMWAMHND.up_ButtonHandler.um_STDButton Pitembottone(<ID>) Pgestito(TRUE)
Il metodo "um_STDButton" ha i seguenti parametri:
- pItemBottone = l'id del bottone da gestire
- pGestito = TRUE il bottone viene visualizzato, FALSE (che è il default) il bottone NON viene visualizzato
- pDefault = TRUE il bottone viene impostato come predefinito FALSE (che è il default) il bottone è normale
Si assume per default che i Tasti Standard sono gestiti con la routine uWAMEvent_18 :
INVOKE Method(£avFrameworkManager.avRegisterEvent) Named(FP_RBTSTD.CLICK) Signalaswamevent(18)
Nella evtroutine associata si fa la distinzione a seconda del'item selezionato e si dovrà richiamare dei metodi predefiniti
creati all'interno della WAM (es: um_WAMSalva, um_WAMCerca ecc.)
EVTROUTINE Handling(£avFrameworkManager.uWAMEvent_18) Options(*NOCLEARMESSAGES *NOCLEARERRORS)
£FastPart.uSingName := FP_RBTSTD
£index := £FastPart.UselectItem
CASE (£index)
WHEN (= 1)
£com_owner.um_WAMSalva
WHEN (= 3)
£com_owner.um_WAMCerca
WHEN (= 10)
£com_owner.um_WAMDecodifica
ENDCASE
ENDROUTINE
I Tasti Funzione sono tasti "supplementari" liberi e sono gestiti con la Fast-Part FP_RBTFUN.
Il numero dei bottoni gestiti e le caption vengono definiti all'interno di ogni singola WAM.
Vanno attivati nella routine uExecute: prima va dichiarato il numero dei tasti gestiti, e poi devono essere definiti.
£DMWAMHND.up_ButtonHandler.um_FUNButtonGestiti Ptotalepulsanti(2)
£DMWAMHND.up_ButtonHandler.um_FUNButton Pitembottone(1) Pgestito(TRUE) Pcaption(*MTXTnnnnnnnnn)
£DMWAMHND.up_ButtonHandler.um_FUNButton Pitembottone(2) Pgestito(TRUE) Pcaption(*MTXTnnnnnnnnn)
Si assume per default che i Tasti Standard sono gestiti con la routine uWAMEvent_19 :
INVOKE Method(£avFrameworkManager.avRegisterEvent) Named(FP_RBTFUN.CLICK) Signalaswamevent(19)
Nella evtroutine associata si fa la distinzione a seconda del'item selezionato e si dovrà richiamare dei metodi predefiniti
creati all'interno della WAM (es: um_WAMFun01, um_WAMFun02 ecc.)
EVTROUTINE Handling(£avFrameworkManager.uWAMEvent_19) Options(*NOCLEARMESSAGES *NOCLEARERRORS)
£FastPart.uSingName := FP_RBTFUN
£index := £FastPart.UselectItem
CASE (£index)
WHEN (= 1)
£com_owner.um_WAMFun01
WHEN (= 2)
£com_owner.um_WAMFun02
ENDCASE
ENDROUTINE
REGOLE PER I FILTRI
Template di riferimento: EDVLFWFILT
Cercare di ottimizzare i filtri per non generare Instance-List enormi con tempi di attesa lunghi. E' preferibile fare pìù filtri e/o gestire la paginazione.
Gli accessi ai file vanno sempre ottimizzati al massimo sfruttando SELECT differenti in base all'ambiente in cui viene eseguito il filtro (AS400 o PC) tramite il controllo
della variabile *PLATFORM
Va sempre e solo abilitato il tasto "Cerca" (id 3)
Le selezioni Da / A vanno gestite in questo modo:
Se entrambi i parametri DA / A sono vuoti, quello A va assegnato con *HIVALALP o *HIVALNUM
Se è inserito SOLO il parametro DA, quello A va assegnato = a DA
In DMWAMHND sono presenti i metodi um_CheckFldRangeA e um_CheckFldRangeN
Settare le FastPart delle date in visualizzazione standard vuote (NO = *DDMMYYYY) (devono avere il parametro "AllowNull" a TRUE)
Centralizzare la gestione dell'intance-list in un'apposita reusable-part che comprende l'eventuale gestione della paginazione. Questo per avere un unico punto
in cui fare l'AddToList in modo che future espansioni della lista stessa (campi in più e/o filtri aggiuntivi) siano facilmente manutenibili.
Per gestire il file di appoggio per la paginazione utilizzare un nome univoco considerando l'id finestra:
£idfile := £DMWAMHND.up_UserPathHandler.um_GetUserTmp(<Utente>) + *pathdelim + £DMWAMHND.up_IdFinestra + "_" + <Identificativo File>
La FastPart della paginazione è FP_RED02 e va inserita nella parte superiore della pagina XSL.
Filtri nascosti
In alternativa ai normali filtri è possibile implementare anche dei filtri nascosti, ovvero che non hanno la pagina visibile e quindi lavorano senza interazione con l'utente.
Per far si che un filtro agisca come nascosto è necessario imopstare la proprietà £ThisFilter.avHiddenFilter = TRUE all'interno della "uExecute".
In esecuzione la porzione della fiestra occupata solitamente dai filtri verrà utilizzata intermente dall'instance-list.
Questo fa capire che ci pùo essere un solo filtro nascosto per ogni BO.
Popolamento Instance-List
Il popolamento iniziale dell'Instance-List è affidato ai filtri, bisogna comunque ricordare che un eventuale aggiornamento della stessa va fatto al'interno dei command-handler
tramite la reusable-part di gestione
Popolamento Standard
£avListManager.BeginListUpdate
£avListManager.ClearList
SELECT (<CAMPI>) FROM(<FILE>)
£avListManager.AddToList VISUALD1(<CAMPO1>)
VISUALID2(<CAMPO2>)
AKEYn(<CAMPO3>)
NKEYn(<CAMPO4>)
ACOLUMNn(<CAMPO5>)
NCOLUMNn(<CAMPO6>)
BUSINESSOBJECTTYPE(<BOTYPE>)
ENDSELECT
£avListManager.EndListUpdate
Popolamento padre-figlio con caricamento figlio insieme al padre
£avListManager.BeginListUpdate
£avListManager.ClearList
SELECT (<CAMPI>) FROM(<FILE_PADRE>)
£avListManager.AddToList VISUALD1(<CAMPO1>)
VISUALID2(<CAMPO2>)
AKEYn(<KEY1_PADRE>)
NKEYn(<KEY2_PADRE>)
ACOLUMNn(<CAMPO5>)
NCOLUMNn(<CAMPO6>)
BUSINESSOBJECTTYPE(<BOTYPE_PADRE>)
SELECT (<CAMPI>) FROM(<FILE_FIGLIO>) WITH_KEY(<KEY_PADRE>)
£avListManager.AddToList VISUALD1(<CAMPO1>)
VISUALID2(<CAMPO2>)
AKEYn(<KEY1_PADRE>)
NKEYn(<KEY2_PADRE>)
AKEYn+1(<KEY1_FIGLIO>)
NKEYn+1(<KEY2_FIGLIO>)
ACOLUMNn(<CAMPO5>)
NCOLUMNn(<CAMPO6>)
BUSINESSOBJECTTYPE(<BOTYPE_FIGLIO>)
ENDSELECT
ENDSELECT
£avListManager.EndListUpdate
Popolamento padre-figlio con caricamento del figlio alla scelta del padre
£avListManager.BeginListUpdate
£avListManager.ClearList
SELECT (<CAMPI>) FROM(<FILE_PADRE>)
£avListManager.AddToList VISUALD1(<CAMPO1>)
VISUALID2(<CAMPO2>)
AKEYn(<KEY1_PADRE>)
NKEYn(<KEY2_PADRE>)
ACOLUMNn(<CAMPO5>)
NCOLUMNn(<CAMPO6>)
BUSINESSOBJECTTYPE(<BOTYPE_PADRE>)
ENDSELECT
£avListManager.EndListUpdate
Quando l'utente espande un padre il FrameWork chiamerà la funzione associata per il caricamento dei figli:
CASE SRC_BOTYPE
WHEN (= <BOTYPE_PADRE>)
SELECT (<CAMPI>) FROM(<FILE_FIGLIO>) WITH_KEY(<KEY_PADRE>)
£avListManager.AddToList VISUALD1(<CAMPO1>)
VISUALID2(<CAMPO2>)
AKEYn(<SRC_AKEYn>)
NKEYn(<SRC_NKEYn>)
AKEYn+1(<KEY1_FIGLIO>)
NKEYn+1(<KEY2_FIGLIO>)
ACOLUMNn(<CAMPO5>)
NCOLUMNn(<CAMPO6>)
BUSINESSOBJECTTYPE(<BOTYPE_FIGLIO>)
ENDSELECT
ENDCASE
POPOLAMENTO CO BO PEER
£avListManager.BeginListUpdate
£avListManager.ClearList
SELECT (<CAMPI>) FROM(<FILE_A>)
£avListManager.AddToList VISUALD1(<CAMPO_A1>)
VISUALID2(<CAMPO_A2>)
AKEYn(<CAMPO_A3>)
NKEYn(<CAMPO_A4>)
ACOLUMNn(<CAMPO_A5>)
NCOLUMNn(<CAMPO_A6>)
BUSINESSOBJECTTYPE(<BOTYPE_A>)
ENDSELECT
SELECT (<CAMPI>) FROM(<FILE_B>)
£avListManager.AddToList VISUALD1(<CAMPO_B1>)
VISUALID2(<CAMPO_B2>)
AKEYn(<CAMPO_B3>)
NKEYn(<CAMPO_B4>)
ACOLUMNn(<CAMPO_B5>)
NCOLUMNn(<CAMPO_B6>)
BUSINESSOBJECTTYPE(<BOTYPE_B>)
ENDSELECT
£avListManager.EndListUpdate
POPOLAMENTO CON SUB TYPE
£avListManager.BeginListUpdate
£avListManager.ClearList
SELECT (<CAMPI>) FROM(<FILE>)
CASE <CAMPOX>
WHEN (= "A")
<CAMPO_SUBTYPE> := "SUB01"
WHEN (= "B")
<CAMPO_SUBTYPE> := "SUB02"
WHEN (= "C")
<CAMPO_SUBTYPE> := "SUB03"
ENDCASE
£avListManager.AddToList VISUALD1(<CAMPO1>)
VISUALID2(<CAMPO2>)
AKEYn(<CAMPO3>)
NKEYn(<CAMPO4>)
ACOLUMNn(<CAMPO5>)
NCOLUMNn(<CAMPO6>)
BUSINESSOBJECTTYPE(<BOTYPE>)
SUBTYPE(<CAMPO_SUBTYPE>)
ENDSELECT
£avListManager.EndListUpdate
REGOLE PER I COMMAND-HANDLER
Template di riferimento: EDVLWFBASE / EDVLFWCMD1 / EDVLFWCMD2
1. Se si tratta di un BO Command impostare il titolo della finestra nel seguente modo:
WEB_MAP FOR(*BOTH) FIELDS((£ED_TITLE *PRIVATE))
Nella "uExecute" assegnare il valore:
£ED_TITLE := *COMPONENT_DESC
2. Le autorizzazioni per i tasti "Salva", "Elimina", "Conferma", "Elimina (a livello di Lista)" sono automaticamente disabilitate dall'architettura.
Per tutti gli altri tasti che comportanto INSERT/UPDATE/DELETE su file (es. "Forza") è necessario controllare l'autorizzazione al BO tramite la proprietà
£DMWAMHND.up_CanWriteBO ed disabilitare il tasto in caso sia FALSE.
Per i Command "Elimina" il controllo va fatto prima di emettere il messaggio di richiesta conferma e nel caso che l'utente non sia autorizzato, emettere solo
il messaggio "Non autorizzato" ed interrompere l'elaborazione.
Nel caso in cui un tasto non debba sottostare in alcuna maniera alle autorizzazioni (es. "Conferma" in un programma di stampa) impostare il parametro
OverrideAuth a TRUE nel metodo £DMWAMHND.up_ButtonHandler.um_STDButtonEnabled.
3. Tutti i campi "descrizione" devono essere inseriti in una WEB_MAP FOR(*OUTPUT) con attributo (*OUTPUT) e decodificati sempre nella "uTerminate".
In questo modo si evita di dover gestire il tasto "Decodifica" che resta invece valido solo nei casi in cui il command prevede uno switch automatico.
4.Nelle WEB_MAP DEVONO essere presenti solo i campi che effettivamente vengono utilizzati nella pagina XSL.
Quelli che possono essere riletti dal database o dall'Instance-List NON devono essere assolutamente inseriti nelle WEB_MAP per non appesantire le pagine,
ma vanno inizializzati nella "uInitialize"(se servono sempre) o "uExecute" (se servono solo la prima volta).
5.Se nella pagina XSL sono previste delle condizioni, queste devono essere gestite tramite la valorizzazione di campi passati poi nella WEB_MAP, in modo da
tenere la logica applicativa il più possibile all'interno del programma.
E consigliabile chiamare i nomi di questi campi con un prefisso comune (es. VISxxxxxx) in modo da poterli individuare facilmente anche all'interno della pagina XSL.
6.Se un Command-Handler (WAM) è utilizzato per gestire diversi Command è possibile utilizzare i campi avAlphaArg o avNumArg impostabili dal FrameWork:
In questo modo leggendoli nella WAM con £ThisHandler.avAlphaArg oppure £ThisHandler.avNumericArg possiamo capire chi ha chiamato
la WAM e comportarci di conseguenza.
7.I Command-handler (WAM) a livello di instance-list devono controllare se esiste l'instanza selezionata tramite:
£avlistmanager.Getcurrentinstance AKEY1(<Key>) NKEY1(<Key>) FOUND(£FLTROVATO)
IF (£FLTROVATO.asBoolen)
<Istruzioni>
ENDIF
Imposto il tasto "Salva" a disabilitato se l'item non c'è
£DMWAMHND.up_ButtonHandler.um_stdbuttonenabled PITEMBOTTONE(1) PENABLED(£FLTROVATO.asboolean)
WORKING LIST
Tutte le working-list all'interno dei command dovranno essere gestite visualizzando 15 record per volta e utilizzando la paginazione
per scorrerle.
Il tutto avviebe utilizzando 2 working-list di nome LISTAFULL e LISTAVIEW.
LISTAFULL conterrà tutti i record della selezione mentre LISTAVIEW (max 15 record) visualizzerà una pagina alla volta.
DEF_LIST Name(£LISTAFULL) Fields(£campo0 £CAMPO1 £CAMPO2 £CAMPO3) Counter(£LISTCOUNT) Type(*Working) Entrys(*MAX)
DEF_LIST Name(£LISTAVIEW) Fields(£campo0 £CAMPO1 £CAMPO2 £CAMPO3) Type(*Working) Entrys(15)
includere anche i seguenti campi
DEFINE Field(£CUR_REC) Reffld(£LISTCOUNT) ---> per memorizzare il primo elemento della pagina visualizzata
DEFINE Field(£WKLFILE) Type(*CHAR) Length(256) ---> per memorizzare il percorso completo del File dove verrà salvata la lista completa
DEFINE Field(£WKLSCELTI) Type(*CHAR) Length(256) ---> per memorizzare il percorso completo del File dove verranno salvate le selezioni
che dovranno essere inclusi in una WEB_MAP in Hidden
WEB_MAP For(*both) Fields(£LISTAVIEW (£CUR_REC *hidden) (£WKLFILE *HIDDEN))
E' possibile gestire anche la multiselezione delle righe utilizzando il campo £FLSCELTO (riferito a R_FLBASE) in LISTAFULL ed la fast-part FP_RCKSEL
DEFINE Field(£FLSCELTO) Reffld(£R_FLBASE)
DEFINE Field(£SELCOUNT) Reffld(£LISTCOUNT)
DEFINE Field(£SELFIELD) Reffld(<CAMPO CHIAVE DA MEMORIZZARE>)
e definire questa lista utilizzata per memorizzare le righe scelte
DEF_LIST Name(£LISTASEL) Fields(£SELFIELD) COUNTER(£SELCOUNT) Type(*Working) Entrys(*MAX)
Si assume per default che i messaggi dei pulsanti di Paginazione siano gestiti con l'evento n° 20 da registrare nella webroutine uHandleEvent
INVOKE Method(£avFrameworkManager.avRegisterEvent) Named(FP_RED02.CLICK) Signalaswamevent(20)
Nella routine uExecute della Wam si deve inizializzare il nome del file di appoggio (che verrà composto dalla cartella dell'utente più un ID univoco)
IF (£WKLFILE = *BLANK)
£avFrameWorkManager.avrestorevalue WITHID1(*COMPONENT) WITHID2(<ID PER MEMORIZZARE IL VALORE>) TOAVALUE(£WKLFILE) RETURNCODE(£RETCODA)
IF (£retcoda <> 'OK')
£WKLFILE := £DMWAMHND.up_UserPathHandler.um_GetUserTmp( *USER ) + *PathDelim + £DMWAMHND.up_IDUnivocoHandler.um_GeneraID
£avFrameWorkManager.avsavevalue WITHID1(*COMPONENT) WITHID2(<ID PER MEMORIZZARE IL VALORE>) FROMAVALUE(£WKLFILE)
ENDIF
ENDIF
Operazioni su Working List
E' possibile gestire 2 tipi di operazioni per le working-list:
- a livello di lista
- a livello di riga
Le operazioni a livello di lista devono essere utilizzate in presenza della multiselezione
Le operazioni BASE che si possono gestire sono:
1. Modifica
2. Elimina
3. Dettagli
4. Stampa
5. Seleziona
si dovranno abilitare solo quelle necessarie tramite l'istruzione:
£DMWAMHND.up_ButtonHandler.um_IMLButtonDefine pOccurrence(£STD_NUM) pBottoniGestiti('2 4')
("pBottoniGestiti" è una stringa che contiene i "numeri" dei pulsanti da attivare separati da spazi)
che deve essere inserita all'interno del loop di caricamento della lista dove £STD_NUM rappresenta l'entrata corrente della lista.
Si possono gestire anche tasti funzioni addizionali tramite:
£DMWAMHND.up_ButtonHandler.um_IMLAddButtonFunc pOccurrence(£STD_NUM) pImage(<Nome dell'Immagine>) pImageHint(<Variabile Multilingua>)
All'occorrenza, sempre nel ciclo della lista, è possibile abilitare o disabilitare un pulsante con:
£DMWAMHND.up_ButtonHandler.um_IMLButtonEnabled pItemBottone(<Indice del Bottone>) pOccurrence(£STD_NUM) pEnabled([TRUE/FALSE])
Nel caso di devono utilizzare sia tasti Base che tasti funzione attivare SEMPRE PRIMA quelli Base
!!!!!! ATTENZIONE !!!!!!
A DIFFERENZA DEI PULSANTI STANDARD DOVE OGNI PULSANTE HA IL SUO ITEM FISSO NELL'EVENTO, NELLE LISTE GLI ITEM DEI PULSANTI VENGONO ASSEGNATI NELL'ORDINE DI ATTIVAZIONE:
ES:
se attivo um_IMLButtonDefine pBottoniGestiti('2 4')
il Pulsante "2 - Elimina" ha indice 1
il Pulsante "4 - Stampa" ha indice 2
se attivo um_IMLButtonDefine pBottoniGestiti('4 2')
avviene esattamente il contrario...
lo stesso discorso vale per i tasti funzione aggiuntivi che seguono la numerazione:
ES:
se attivo um_IMLButtonDefine pBottoniGestiti('2 3 4')
e poi um_IMLAddButtonFunc pImage("IMg1")
um_IMLAddButtonFunc pImage("IMg2")
avrò la seguente mappatura:
Indici Tasti
1 Tasto Base "2"
2 Tasto Base "3"
3 Tasto Base "4"
4 Tasto Funzione "1"
5 Tasto Funzione "2"
Per le operazioni a livello di lista passare il parametro pOperazioniComuni a TRUE
Si assume per default che i messaggi dei pulsanti Lista siano gestiti con l'evento n° 17 da registrare nella webroutine uHandleEvent
Per le operazioni a livello di riga registrare:
INVOKE Method(£avFrameworkManager.avRegisterEvent) Named(FP_RIMLOP.CLICK) Signalaswamevent(17)
Per le operazioni a livello di lista registrare:
INVOKE Method(£avFrameworkManager.avRegisterEvent) Named(FP_RBTCOM.CLICK) Signalaswamevent(17)
sarà nella evtroutine associata che si fa la distinzione a secondo del'item selezionato, come per i precedenti bottoni, ma si deve indicare anche l'occurrence.
--EVTROUTINE Handling(£avFrameworkManager.uWAMEvent_17) Options(*NOCLEARMESSAGES *NOCLEARERRORS)
|
Per le operazioni a livello di riga utilizzare:
| £FastPart.uSingName := FP_RIMLOP
Per le operazioni a livello di lista utilizzare:
| £FastPart.uSingName := FP_RBTCOM
| £std_num := £FastPart.USelectOccurrence
| £FastPart.UsingOccurrence := £std_num
| £index := £FastPart.UselectItem
|
| --CASE (£index)
| |
| |--WHEN (= 1)
| | ********** TASTO MODIFICA
| |
| |--WHEN (= 2)
| | ********** TASTO ELIMINA
| |
| |--WHEN (= 3)
| | ********** TASTO DETTAGLI
| |
| |--WHEN (= 4)
| | ********** TASTO STAMPA
| |
| --ENDCASE
|
--ENDROUTINE
Per le label utilizzare la descrizione del campo (eventualmente modifcata). Solo nelle eccezioni utilizzare le variabili multilingua
Nelle liste utilizzare sempre le variabili multilingua
I campi all'interno della LISTAVIEW devono avere l'attributo *OUTPUT per far si che la pagina HTML non genere campi Elemento
===================================================================================
DISEGNO DELLA PAGINA XSL
formattare la visualizzazione delle taglie(c'è un documento di Stefano Foresi).
ed_display_img per visualizzazione immagini.
descrivere metodo da utlizzare per mettere le descrizioni vicino ai codice per il ritorno automatico dalla pop-up
spiegare la differenza tra <xsl:if> e style="display: xxxx"