En los proyectos en los que he trabajado desarrollando personalizaciones para PEOPLESOFT siempre me he encontrado con el siguiente requerimiento:
- La página de parámetros del reporte a desarrollar debe permitir para el campo X (generalmente un campo XLAT) la selección de uno, todos o múltiples valores.
Como desarrollador asumí que esté tipo de comportamiento es nativo a PEOPLESOFT ya que se puede encontrar en las distintas páginas de búsqueda que genera el aplicativo automáticamente. En el siguiente ejemplo se puede ver el comportamiento citado:
Dentro de PEOPLESOFT no existe una forma simple y automática de replicar esté comportamiento, según algunos foros en internet la forma de realizarlo es a través de la utilización del iScrip.
A continuación expongo un ejemplo de como realizar una lista de selección multiple dentro de una página de PEOPLESOFT
Lo primero que se debe hacer es crear un record para almacenar la información que se seleccionará. Por ejemplo para la imagen anterior se deberían almacenar los valores para "Comprobante Reclam", "Pago Único" y "Reversión" lo cuales fueron seleccionados por el usuario. El registro se va a llamar Q_MULLIST_TBL y es de tipo table y debe tener los campos que se muestran en la figura. Este registro puede servir para almacenar todos los datos de todas la listas de selección que se utilicen dentro de PEOPLESOFT.
Generalmente la ejecución de los reportes se hace por control de ejecución y por id de usuario, por esa razón este registro tiene esos 2 campos.
El campo FIELDNAME es para indicar a que campo (de tipo XLAT) pertenecen esos registros.
El campo PARAMETERNAME es un identificador por si es necesario introducir dentro de un mismo control de ejecución múltiples listas de selección para el mismo campo.
Y por último el campo VALUE50_FLD1 es el campo donde se almacenará el valor seleccionado.
Cada vez que se quiere introducir código iScript dentro de una página Peoplesoft se debe tener un campo de tipo HTML Area, este campo permite generar código HTML independiente del COMPONENT BUFFER.
Para lo anterior se debe crear otro record, esta vez de tipo DERIVED/WORK para introducir un campo de tipo HTML Area.
Adicionalmente este record contendrá el campo TREECTLEVENT el cual tendrá como función controlar los eventos que se ejecutarán cuando se modifiquen los datos que se incluyan dentro del campo HTML Area (En nuestro caso cuando se marquen o desmarquen valores dentro de nuestra lista.)
El campo FIELDNAME es para indicar a que campo (de tipo XLAT) pertenecen esos registros.
El campo PARAMETERNAME es un identificador por si es necesario introducir dentro de un mismo control de ejecución múltiples listas de selección para el mismo campo.
Y por último el campo VALUE50_FLD1 es el campo donde se almacenará el valor seleccionado.
Cada vez que se quiere introducir código iScript dentro de una página Peoplesoft se debe tener un campo de tipo HTML Area, este campo permite generar código HTML independiente del COMPONENT BUFFER.
Para lo anterior se debe crear otro record, esta vez de tipo DERIVED/WORK para introducir un campo de tipo HTML Area.
Adicionalmente este record contendrá el campo TREECTLEVENT el cual tendrá como función controlar los eventos que se ejecutarán cuando se modifiquen los datos que se incluyan dentro del campo HTML Area (En nuestro caso cuando se marquen o desmarquen valores dentro de nuestra lista.)
El record se va a llamar Q_HTML_WRK y debe quedar como se ven en la figura:
A continuación se describen las funciones que necesarias para generar nuestra lista de selección múltiple. Estas funciones se deben escribir en el evento FIELDFORMULA del campo HTMLAREA del record Q_HTML_WRK
La primera función es la función que permite pintar, cargar los valores seleccionados y actualizar los valores de nuestra lista.
Function getHTMLMultiSelect(&str_oprid As string, &str_run_cntl_id As string, &str_recordname As string, &str_fieldname As string, &str_parametername As string, &str_pagename As string, &str_cntrlfield As string, &bol_Init As boolean)
Local string &str_html;
Local Field &fld_campo;
Local string &str_field;
Local Rowset &rs_Xlat, &rs_selected;
Local Record &rec_field;
Local number &nbr_i;
Local array of string &arr_selected;
&str_html = "<select name='" | &str_parametername | "' onchange=""javascript:submitAction_win0(document.win0,'#ICSetField" | &str_pagename | "." | &str_cntrlfield | ".X1');"" multiple= 'true'>";
&str_field = &str_recordname | "." | &str_fieldname;
&fld_campo = GetField(@(&str_field));
If &fld_campo.IsEditXlat Then
&arr_selected = CreateArrayRept("", 0);
If &bol_Init Then
&rs_selected = CreateRowset(Record.Q_MULLIST_TBL);
&rs_selected.Fill("WHERE FILL.OPRID = :1 AND FILL.RUN_CNTL_ID = :2 AND FILL.FIELDNAME = :3 AND FILL.PARAMETERNAME = :4", &str_oprid, &str_run_cntl_id, &str_fieldname, &str_parametername);
For &nbr_i = 1 To &rs_selected.ActiveRowCount
&arr_selected.Push(&rs_selected(&nbr_i).GetRecord(1).GetField(Field.VALUE50_FLD1).Value);
End-For;
Else
&arr_selected = %Request.GetParameterValues(&str_parametername);
End-If;
&rs_Xlat = CreateRowset(Record.PSXLATITEM);
&rs_Xlat.Fill("WHERE FILL.FIELDNAME = :1 and EFFDT = (select max(EFFDT) from PSXLATITEM B where B.FIELDNAME = :1 and FILL.FIELDVALUE = B.FIELDVALUE and EFFDT <= %CURRENTDATEIN)", &str_fieldname);
&nbr_i = 1;
For &nbr_i = 1 To &rs_Xlat.ActiveRowCount
&fld_campo.Value = &rs_Xlat(&nbr_i).GetRecord(1).GetField(Field.FIELDVALUE).Value;
If &arr_selected.Find(&rs_Xlat(&nbr_i).GetRecord(1).GetField(Field.FIELDVALUE).Value) <> 0 Then
&str_html = &str_html | "<option value='" | &rs_Xlat(&nbr_i).GetRecord(1).GetField(Field.FIELDVALUE).Value | "' selected='true'>" | &fld_campo.LongTranslateValue | "</option>"
Else
&str_html = &str_html | "<option value='" | &rs_Xlat(&nbr_i).GetRecord(1).GetField(Field.FIELDVALUE).Value | "' >" | &fld_campo.LongTranslateValue | "</option>"
End-If;
End-For;
&str_html = &str_html | "</select>";
Q_HTML_WRK.HTMLAREA.Value = &str_html;
If Not &bol_Init Then
Q_HTML_WRK.TREECTLEVENT.Value = "";
End-If;
End-If;
End-Function;
A continuación se describen los parámetros de la función:
- &str_oprid: Usuario que está creando los datos
- &str_run_cntl_id: Control de ejecución que se está creando
- &str_recordname: Registro en el que se encuentra el campo XLAT para el cual se va a almacenar la información.
- &str_fieldname: Campo XLAT para el que se va a almacenar la información
- &str_parametername: Identificador que se le va a dar al campo
- &str_pagename: nombre de la página que está ejecutando el control
- &str_cntrlfield: es el campo de control, generalmente es TREECTLEVENT que es el campo que se utiliza para controlar los eventos que ocurrirán en el HTML Area
- &bol_Init: Indica si se está inicializando la lista (Rowinit) o si se está modificando (fieldchange)
El objetivo del fragmento que presentando a continuación es crear el código html que va a marcar el campo TREECTLEVENT para ejecutar el evento FIELDCHANGE cuando se dé clic dentro de la lista, la cual está representanda por el comando “<select” el cual indica que se está creando una lista, y el parámetro “multiple=’true’” indica que se pueden seleccionar múltiples valores dentro de ésta.
La función submitAction_win0 es una función javascript que provee peoplesoft, y que permite marcar un control para la ejecución del evento FIELDCHANGE
&str_html = "<select name='" | &str_parametername | "' onchange=""javascript:submitAction_win0(document.win0,'#ICSetField" | &str_pagename | "." | &str_cntrlfield | ".X1');"" multiple= 'true'>"; El siguiente fragmento de código verifica si el campo que se está usando es XLAT de no ser así no hará nada.
&str_field = &str_recordname | "." | &str_fieldname;
&fld_campo = GetField(@(&str_field));
If &fld_campo.IsEditXlat Then
El código presentando a continuación verifica los valores seleccionados dentro de la lista. Si se está iniciando la lista, se verifican los valores que están guardados en la base de datos, de lo contrario sí se está ejecutando en el FIELDCHANGE se verifican los valores que se encuentran actualmente seleccionados en la lista. En este punto es que entra jugar el iScript, la variable del sistema %Request permite acceder directamente al html, usando esta variable podemos obtener los valores seleccionados actualmente en la página, utilizando la función GetParameterValues obtenemos los valores marcados por el usuario.
&arr_selected = CreateArrayRept("", 0);
If &bol_Init Then
&rs_selected = CreateRowset(Record.Q_MULLIST_TBL);
&rs_selected.Fill("WHERE FILL.OPRID = :1 AND FILL.RUN_CNTL_ID = :2 AND FILL.FIELDNAME = :3 AND FILL.PARAMETERNAME = :4", &str_oprid, &str_run_cntl_id, &str_fieldname, &str_parametername);
For &nbr_i = 1 To &rs_selected.ActiveRowCount
&arr_selected.Push(&rs_selected(&nbr_i).GetRecord(1).GetField(Field.VALUE50_FLD1).Value);
End-For;
Else
&arr_selected = %Request.GetParameterValues(&str_parametername);
End-If;
En el siguiente paso se recorren los valores activos del XLAT, escribirlos dentro de la lista usando la opción "<option" y asignar este fragmento de HTML al campo HTMLAREA para que sea visualizado dentro de la página.
&rs_Xlat = CreateRowset(Record.PSXLATITEM);
&rs_Xlat.Fill("WHERE FILL.FIELDNAME = :1 and EFFDT = (select max(EFFDT) from PSXLATITEM B where B.FIELDNAME = :1 and FILL.FIELDVALUE = B.FIELDVALUE and EFFDT <= %CURRENTDATEIN)", &str_fieldname);
&nbr_i = 1;
For &nbr_i = 1 To &rs_Xlat.ActiveRowCount
&fld_campo.Value = &rs_Xlat(&nbr_i).GetRecord(1).GetField(Field.FIELDVALUE).Value;
If &arr_selected.Find(&rs_Xlat(&nbr_i).GetRecord(1).GetField(Field.FIELDVALUE).Value) <> 0 Then
&str_html = &str_html | "<option value='" | &rs_Xlat(&nbr_i).GetRecord(1).GetField(Field.FIELDVALUE).Value | "' selected='true'>" | &fld_campo.LongTranslateValue | "</option>"
Else
&str_html = &str_html | "<option value='" | &rs_Xlat(&nbr_i).GetRecord(1).GetField(Field.FIELDVALUE).Value | "' >" | &fld_campo.LongTranslateValue | "</option>"
End-If;
&str_html = &str_html | "</select>";
Q_HTML_WRK.HTMLAREA.Value = &str_html;
Por último se reinicia el valor del campo TREECTLEVENT.
La otra función que se debe desarrollar es la que permite guardar los datos seleccionados a la base de datos
Function saveHTMLMultiSelect(&str_oprid As string, &str_run_cntl_id As string, &str_fieldname As string, &str_parametername As string)
Local string &str_html;
Local Field &fld_campo;
Local string &str_field;
Local Rowset &rs_Xlat, &rs_selected;
Local number &nbr_i;
Local array of string &arr_selected;
Local Record &rec_tcf_mullist_tbl;
SQLExec("DELETE FROM PS_TCF_MULLIST_TBL WHERE OPRID = :1 AND RUN_CNTL_ID = :2 AND FIELDNAME = :3 AND PARAMETERNAME = :4", &str_oprid, &str_run_cntl_id, &str_fieldname, &str_parametername);
&arr_selected = %Request.GetParameterValues(&str_parametername);
For &nbr_i = 1 To &arr_selected.Len
&rec_tcf_mullist_tbl = CreateRecord(Record.TCF_MULLIST_TBL);
&rec_tcf_mullist_tbl.OPRID.Value = &str_oprid;
&rec_tcf_mullist_tbl.RUN_CNTL_ID.Value = &str_run_cntl_id;
&rec_tcf_mullist_tbl.FIELDNAME.Value = &str_fieldname;
&rec_tcf_mullist_tbl.PARAMETERNAME.Value = &str_parametername;
&rec_tcf_mullist_tbl.VALUE50_FLD1.Value = &arr_selected [&nbr_i];
&rec_tcf_mullist_tbl.Insert();
End-For;
End-Function;
Primero que todo se elimina la información que existe actualmente en la base de datos:
SQLExec("DELETE FROM PS_TCF_MULLIST_TBL WHERE OPRID = :1 AND RUN_CNTL_ID = :2 AND FIELDNAME = :3 AND PARAMETERNAME = :4", &str_oprid, &str_run_cntl_id, &str_fieldname, &str_parametername);
Obtenemos la información actualmente seleccionada en la lista, utilizando el objeto iScript %Request:
&arr_selected = %Request.GetParameterValues(&str_parametername);
Insertamos los valores seleccionados a la base de datos:
For &nbr_i = 1 To &arr_selected.Len
&rec_tcf_mullist_tbl = CreateRecord(Record.TCF_MULLIST_TBL);
&rec_tcf_mullist_tbl.OPRID.Value = &str_oprid;
&rec_tcf_mullist_tbl.RUN_CNTL_ID.Value = &str_run_cntl_id;
&rec_tcf_mullist_tbl.FIELDNAME.Value = &str_fieldname;
&rec_tcf_mullist_tbl.PARAMETERNAME.Value = &str_parametername;
&rec_tcf_mullist_tbl.VALUE50_FLD1.Value = &arr_selected [&nbr_i];
&rec_tcf_mullist_tbl.Insert();
End-For;
Hasta este momento se han creado los objetos que se van a reutilizar en cada una de las páginas donde se haga necesario incluir la lista.
Los pasos para crear una página que use este control son los siguientes:
- crear el registro del control de ejecución del reporte para el cual se va a utilizar la página. El registro tiene como mínimo OPRID y RUN_CNTL_ID las cuales deben ser llaves y llaves de búsqueda. El registro que se va a utilizar en el ejemplo se llama Q_PRB_LISTA_TBL
- crear la página en la cual se va a mostrar la lista de selección.
- Agregar a la página la Subpagina PRCSRUNCNTL_SBP y configurar el campo “To” para que apunte al registro Q_PRB_LISTA_TBL
- Crear un registro de tipo derived que contenga el campo para el cual se hará la lista de selección múltiple. El campo puede ser cualquiera que tenga definido un XLAT, por ejemplo el campo ACCESS_LEVEL. En este caso se utilizará un campo llamado Q_PRUEBA_LISTA y el recrod se llamará Q_PRB_LISTA_WRK
- Colocar el campo en la página donde va a ser utilizado el control, debe marcarse como Display Only e Invisible
- Arrastrar el campo HTMLAREA del record Q_HTML_WRK a la página
- Arrastrar el campo TREECTLEVENT del record Q_HTML_WRK a la página y lo marcarlo como invisible y Modifiable by Javascript
- La página debe quedar como se ve en la figura:
- En el evento rowinit del Q_PRB_LISTA_WRK.Q_PRUEBA_LISTA agregar el llamado a la función para inicializar la lista de selección:
Declare Function getHTMLMultiSelect PeopleCode Q_HTML_WRK.HTMLAREA FieldFormula;
getHTMLMultiSelect(Q_PRB_LISTA_TBL.OPRID.Value, Q_PRB_LISTA_TBL.RUN_CNTL_ID.Value, "Q_PRB_LISTA_WRK", "Q_PRUEBA_LISTA", "VALORES", "Q_PRB_LISTA_PAGE", "TREECTLEVENT", True);
- En el evento SavePostChange del Q_PRB_LISTA_WRK.Q_PRUEBA_LISTA agregar el llamado a la función para guardar los datos de la lista de selección:
Declare Function SAVEHTMLMultiSelect PeopleCode Q_HTML_WRK.HTMLAREA FieldFormula;
SAVEHTMLMultiSelect(Q_PRB_LISTA_TBL.OPRID.Value, Q_PRB_LISTA_TBL.RUN_CNTL_ID.Value, "Q_PRUEBA_LISTA", "VALORES");
- Crear el Componente, el Menú, registrarlos en el portal y le darles seguridad para poder accederlos.
- Por último agregar el siguiente código al campo TREECTLEVENT del record Q_HTML_WRK a nivel de componente:
Declare Function getHTMLMultiSelect PeopleCode Q_HTML_WRK.HTMLAREA FieldFormula;
getHTMLMultiSelect(Q_PRB_LISTA_TBL.OPRID.Value, Q_PRB_LISTA_TBL.RUN_CNTL_ID.Value, "Q_PRB_LISTA_WRK", "Q_PRUEBA_LISTA", "VALORES", "Q_PRB_LISTA_PAGE", "TREECTLEVENT", False);
- Y listo:
Bueno hasta acá llega la primera entrada de este blog, espero que está información les sea de mucha utilidad en sus proyectos.
Cualquier comentario, sugerencia, duda, pregunta, etc., es bienvenida. Esperen la proxima semana una nueva entrada que tratará sobre una herramienta introducida en PEOPLESOFT 9.0 que permite realizar "Customizaciones" dentro de las aplicaciones disminuyendo el impacto de las mismas y su administración.
USTED ES UN MAESTRO DOCTOR, GRACIAS POR COMPARTIR ESTOS TUTOS !!! OJALA SIGA SUBIENDO MAS !!! SALUDOS !!!
ResponderEliminar