Quantcast
Channel: Oracle
Viewing all articles
Browse latest Browse all 1814

Wiki Page: Implementado Reportes Anidados en Nuestros Informes Clásicos - Oracle APEX 5.0

$
0
0
Written by Clarisa Maman Orfali En este artículo quiero compartir con todos un nuevo plugin llamado “ Pretius APEX Nested Reports ” correspondiente a la categoría de Acciones Dinámicas , que lo he probado y me parece verdaderamente genial para darle un aspecto diferente a nuestros Informes Clásicos. Este plugin implementa a través de una acción dinámica informes anidados dentro de los Informes Clásicos. Esto es algo que no trae nativamente Apex y con este plugin lo podemos implementar. En primera instancia, quiero agradecer a su autor, Bartosz Ostrowski por su gran aporte a la comunidad de desarrolladores APEX. Pretius APEX Nested Reports He re-creado el Informe Clásico del demo que presenta Bartosz en la página del Plugin y en este artículo quiero mostrarte paso a paso cómo realizarlo. El resultado final al que llegaremos será el que se visualiza en las imágenes de abajo. Por un lado, trabajaremos con la columna Customer y mostraremos el detalle de los clientes y luego trabajaremos con la columna Details para mostrar el icono de carrito y allí mostrar el detalle de la Orden realizada por el cliente. Para realizar este demo vamos a necesitar tener en nuestro Espacio de Trabajo las siguientes tablas: DEMO_ORDERS DEMO_CUSTOMERS DEMO_ORDER_ITEMS DEMO_PRODUCT_INFO Estas tablas son parte de la app “ Sample Database Application ” que viene instalada en cada versión de APEX o en el caso de que lo hayas borrado, puedes instalarlo desde Aplicaciones Empaquetadas . Crear Informe Clásico Crear una Página en blanco en nuestra aplicación Crear una región de tipo Informe Clásico que la llamaremos Custom callback En la consulta de Origen ingresamos la siguiente consulta SQL: select distinct DO.ORDER_ID, DO.CUSTOMER_ID, DC.CUST_FIRST_NAME||' '||CUST_LAST_NAME customer, count( ORDER_ITEM_ID ) over (partition by do.order_id) items, DO.ORDER_TOTAL, cast(DO.ORDER_TIMESTAMP as date) order_date from DEMO_ORDERS DO left join DEMO_CUSTOMERS DC on DO.CUSTOMER_ID = DC.CUSTOMER_ID left join DEMO_ORDER_ITEMS DOI on DO.ORDER_ID = DOI.ORDER_ID En las Propiedades del Informe Clásico, sección Avanzada, asignamos el “Identificador Estático” como CUSTOMER_ORDERS . Este es nuestro resultado hasta el momento: Para hacer que nuestro informe clásico sea como el que se muestra en el demo, vamos a ocultar las columnas ORDER_ID y CUSTOMER_ID. Por otro lado queremos que la columna del Customer pueda ser un enlace que permita abrir un popover emergente con la información del cliente. El popover es similar al tooltips; es un pop-up box que aparece cuando el usuario hace clic en un elemento, la diferencia es que el popover puede tener mucho más contenido que el tooltips. Tanto las columnas del Customer_ID y la columna del Order_ID, las vamos a ocultar, importante es recalcar que no vamos a eliminarlas de la consulta SQL ya que se necesita tener las referencias de las mismas en otras columnas. Trabajando con las columnas del Informe Clásico Desde el Diseñador de Páginas, expandimos las columnas del Informe Clásico. Columna del carrito de la compra Seleccionamos la columna ORDER_ID y en Tipo seleccionamos “Columna Oculta” Creamos una nueva columna derivada o virtual (hacemos clic con el botón derecho del mouse sobre Columnas) En Tipo seleccionamos “Texto sin Formato” En Cabecera ingresar el nombre “Details” Cambiar Alineación de Columna a “Centro” En Formato de Columna ingresar en Expresión HTML: #ORDER_ID# Finalmente reordenamos la columna y la colocamos en primer lugar Columna Details Desde el Diseñador de Páginas: Seleccionamos la columna CUSTOMER_ID y en Tipo seleccionamos “Columna Oculta” En Formato de Columna ingresar en Expresión HTML: #CUSTOMER_ID# #CUSTOMER# Guardamos los cambios y vemos los resultados: Hemos llegado a tener el Informe Clásico de la misma forma que nuestro demo inicial. Archivos Bootstrap Antes de implementar el plugin necesitamos disponer de los estilos CSS bootstrap y los archivos JavaScript para usar el popover en una Aplicación en APEX. Podemos bajar los archivos desde la página de Bootstrap AQUÍ o el autor ha preparado los archivos que se pueden bajar desde AQUÍ Importante Aviso : si nosotros descargamos los archivos desde el repositorio oficial, tengamos cuidado de que los archivos de estilos CSS de bootstrap pueden sobre-escribir las reglas CSS de nuestro Tema Universal con estilos redundantes. Necesitamos quitar los estilos redundantes en forma manual para que no cambie la apariencia del Tema Universal. Los archivos preparados por el autor están libres de ese problema, así que yo les aconsejo descargar los archivos del segundo enlace. Una vez descargado el archivo comprimido, lo descomprimimos y tenemos los siguientes archivos: bootstrap.css bootstrap.min.js Tenemos diferentes formas de cargar los archivos en APEX para ser utilizados, una opción es en la sección de página colocar las URLs del CSS y del JavaScript. La otra opción es editar el template de la página y agregar la sección de JavaScript y Cascading Style Sheet. Otra forma es desde los Componentes Compartidos en “Atributos de Interfaz de Usuario” editamos en Escritorio y en la sección JavaScript y Hojas de Estilo en Cascada podemos colocar las URLs correspondientes. Cargar Archivos a nuestro Espacio de Ttrabajo Ahora vamos a cargar los archivos en nuestro Espacio de Trabajo y utilizar las variables de sustitución para hacer la referencia a los mismos, según sea el caso, si lo cargamos en “Archivos de Aplicación Estáticos” usaremos la variable #APP_IMAGES# y en el caso que lo carguemos en “Archivos de Espacio de Trabajo Estáticos” usaremos la variable de sustitución #WORKSPACE_IMAGES”. En mi caso lo subiré en “Archivos de Aplicación Estáticos”, las referencias son las siguientes: #APP_IMAGES#bootstrap.css #APP_IMAGES#bootstrap.min.js Ahora vamos a referenciar los archivos para que nuestra aplicación los pueda leer. Para ello desde la Página de Apex donde tenemos el Informe Clásico en el panel de propiedades vamos a la sección JavaScript e ingresamos lo siguiente en el recuadro URL de Archivo: #APP_IMAGES#bootstrap.min.js. Luego procedemos a la sección CSS y colocamos en el recuadro de URL de Archivo, lo siguiente: #APP_IMAGES#bootstrap.css. Descargar el Plugin Primeramente descargamos el plugin desde AQUÍ Estaría muy agradecida si entre todos ponemos nuestro granito de arena y agradecemos al autor por compartir su trabajo. Para ello, podemos poner nuestro comentario y calificar el plugin en la página de apex-plugin.com, te dejo el enlace AQUÍ Es momento de importar el plugin a nuestro Espacio de Trabajo: Desde los Componentes Compartidos hacemos clic en Plugins y allí lo importamos. Configuración del Plugin Columna Customer Vamos a trabajar primero en la columna de “Customer”, la idea es que en el popover se pueda ver la información del cliente. Para hacer esto, necesitamos crear una Acción Dinámica con una Acción Verdadera que disparará el plugin. En la Página del Diseñador, desde la ficha de Acciones Dinámicas, creamos una nueva Acción Dinámica: Nombre: Customer details Evento: Clic Tipo de Selección: Selector de jQuery Selector de jQuery: td[headers=CUSTOMER] Condición: - Seleccionar - Ámbito de Evento: Dinámico Contenedor Estático (Selector de jQuery): #CUSTOMER_ORDERS Configurar la Acción Verdadera: Acción: Pretius APEX Nested Reports [Plug-In] Mode: Custom template & custom callback Details query: select CUST_FIRST_NAME||' '||CUST_LAST_NAME as "Customer name", CUST_STREET_ADDRESS1||', '||CUST_CITY||' '||CUST_POSTAL_CODE as "Adress", NVL(CUST_EMAIL, 'Not provided') as "E-mail", PHONE_NUMBER1 as "Phone number", CREDIT_LIMIT as "Credit" from DEMO_CUSTOMERS where customer_id = #CUSTOMER_ID# Settings: [x] Cache results [x] Loading indicator Custom Template: {{#data}} Customer name {{Customer name}} Credit {{Credit}} Phone number {{Phone number}} E-mail {{E-mail}} Adress {{Adress}} {{/data}} Custom callback: var //triggering element - cell in column CUSTOMER self = this.callback.triggeringElement, //width of the sidebar - will be needed to calculate popover padding in popover viewport parameteter tBodyNavWidth = $('#t_Body_nav').outerWidth(), //reference to elements that has popover shown other = $('.hasPopover', this.callback.affectedReport ).not(self), //custom padding of popover popoverPadding = tBodyNavWidth == 200 ? 220 : tBodyNavWidth + 20, //modified popover template - it will contain X button to manualy close the popover popoverTemplate = ''+ ' '+ ' '+ ' '+ ' '+ ' '; //hide other popovers and unmark their triggering elements other.popover('hide').removeClass('hasPopover detailsShown'); if (self.is('.hasPopover')) { //if triggering element has popover it will be destroyed and hidden self.popover('hide').removeClass('hasPopover detailsShown'); } else { //recreate popover with custom settings //API: http://getbootstrap.com/javascript/#popovers-options self.popover('destroy').popover({ animation: true, container: 'body', content: this.callback.renderedTemplate, delay: 0, html: true, placement: 'bottom', selector: false, template: popoverTemplate, title: 'Customer details', trigger: 'manual', viewport: { selector: 'body', padding: popoverPadding } }).popover('show').addClass('hasPopover detailsShown'); //force showing the popover and mark it as it has popover shown } Atributos Afectados --- Tipo de Selección: Región Región: Custom callback Arrancar al cargar la Página: No Guardamos los cambios y ejecutamos la página. Podemos observar que al acercar el mouse a la columna del Customer no se muestra el puntero del mismo como que hay un enlace, y por otro lado al hacer clic en el nombre del cliente se abre el popover pero algunos estilos CSS se han perdido en el template personalizado. También podemos ver que la X que cierra la ventana no funciona. Desde la página del Diseñador: 1) Ir a los atributos de página 2) Añadir el siguiente JavaScript en “Declaración de Función y Variable Global” $(document).on('click', '.popoverCloseBtn', function(){ $(this).closest('.popover').popover('hide'); $('.hasPopover').removeClass('hasPopover detailsShown'); }); 3) Añadimos los siguientes estilos CSS para el template personalizado, en la sección CSS En línea: td[headers="CUSTOMER"] { cursor: pointer; } /* custom template */ .popover-content .field { margin-left: 10px; padding: 5px; display: block; } .popover-content .label { font-weight: bold; } .popover-content .value { line-height:30px; } /* popover */ .popover.orderList { max-width: 315px; min-width: 315px; } .popover-content { max-height:400px; overflow: auto; } span.popoverCloseBtn { position: absolute; right: 10px; top: 10px; cursor: pointer; } Guardamos y ejecutamos la página. Hasta aquí es todo el ejemplo que el autor ha desarrollado para implementar su plugin. Quiero agradecer a Bartosz Ostrowski porque le he solicitado si podía pasarme los códigos que usó para implantar la parte del carrito de la compra y muy amablemente me lo ha pasado para compartirlo con toda la comunidad Hispana! Columna Details (icono carrito) En la Página del Diseñador, desde la ficha de Acciones Dinámicas, creamos una nueva Acción Dinámica: Nombre: Details Evento: Clic Tipo de Selección: Selector de jQuery Selector de jQuery: td[headers="DERIVED$01"] Condición: - Seleccionar - Ámbito de Evento: Dinámico Contenedor Estático (Selector de jQuery): #CUSTOMER_ORDERS Configurar la Acción Verdadera: Acción: Pretius APEX Nested Reports [Plug-In] Mode: Custom template & custom callback Details query: select ROWNUM, DPI.CATEGORY, decode( DPI.CATEGORY, 'Womens', 'fa-female', 'Mens', 'fa-male', 'Accessories', 'fa-paperclip', 'fa-question' ) CATEGORY_ICON, DPI.PRODUCT_NAME, DPI.PRODUCT_DESCRIPTION, DPI.LIST_PRICE from DEMO_ORDER_ITEMS DOI left join DEMO_PRODUCT_INFO DPI on DOI.PRODUCT_ID = DPI.PRODUCT_ID where order_id = #ORDER_ID# Settings: [x] Cache results [x] Loading indicator Custom Template: {{#data}} {{PRODUCT_NAME}} {{PRODUCT_DESCRIPTION}} {{LIST_PRICE}} € {{/data}} Custom callback: var self = this.callback.triggeringElement, popoverMaxWidth = $(document).outerWidth() - self.offset().left - 100, t_Body_nav = $('#t_Body_nav').outerWidth(); t_Body_nav = t_Body_nav == 200 ? 150 : t_Body_nav + 10, popoverTemplate = ''+ ' '+ ' '+ ' '+ ' '+ ' ', other = $('.hasPopover', this.callback.affectedReport ).not(self); other.popover('hide'); other.removeClass('hasPopover detailsShown'); if (self.is('.hasPopover')) { self.popover('hide'); self.removeClass('hasPopover detailsShown'); } else { self.popover('destroy'); self.popover({ animation: true, container: 'body', content: this.callback.renderedTemplate, delay: 0, html: true, placement: 'bottom', selector: false, template: popoverTemplate, title: 'List of ordered products', trigger: 'manual', viewport: { selector: 'body', padding: 50 } }).popover('show'); self.addClass('hasPopover detailsShown'); } Atributos Afectados --- Tipo de Selección: Región Región: Custom callback Arrancar al cargar la Página: No Guardamos los cambios. Solo nos resta colocar algunos estilos CSS en los atributos de la Página. Desde el Diseñador de Páginas vamos al recuadro de CSS En Línea y agregamos lo siguiente: .product_row { clear: both; overflow: hidden; } .product_row:nth-child(even) { background-color: #e8e8e8; } .product_row:nth-child(odd) { background-color: #f3f2f2; } .product_row:hover { background: #ffffff; } .product_row:nth-child(even) .fa { opacity: 0.8; } .product_row:nth-child(odd) { opacity: 0.8; } .column { max-width: 70%; display: block; padding: 10px; margin: 0px; float: left; } .product_category { font-size: 40px; line-height: 50px; margin-left: 20px; width: 55px; } .popover-content .product_info { width: 350px; } .title { line-height: 140%; font-size: 140%; } .product_price { float: right; position: relative; transform: rotate(45deg); margin-right: 20px; } .product_price .fa { font-size: 60px; transform: rotate(-45deg); } span.price { font-size: 15px; color: white; position: absolute; top: 28px; left: 23px; } span.currency { top: 25px; position: absolute; left: 48px; color: white; font-size: 10px; } span.popoverCloseBtn { position: absolute; right: 10px; top: 10px; cursor: pointer; Guardamos los cambios y ejecutamos la página. De esta manera, hemos implementado la funcionalidad de reportes anidados haciendo uso del Plugin Pretius APEX Nested Reports. La verdad me gustó mucho agregar esta funcionalidad a nuestros informes clásicos y es por eso que lo comparto con toda la comunidad.

Viewing all articles
Browse latest Browse all 1814

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>