En algunas ocasiones, en nuestras aplicaciones, hay procesos que pueden durar algunos segundos en terminar, por ejemplo cuando se realizar un request a un API o traemos una gran cantidad de data en una consulta de base de datos. Cuando realizamos esto desde el front end, el usuario presionará un botón que ejecutará la solicitud, sin embargo, es necesario mostrarle alguna pantalla de carga que le permita saber que el proceso demorará unos segundos en terminar.

Para hacer esto, apex por default nos brinda un spinner que nos brinda la posibilidad de mostrar un icono de carga utilizando apex.util.showSpinner, sin embargo, no es muy intuitivo y tampoco nos deja mostrar más mensajes o el tiempo de carga.

Es por ello que decidí implementar la librería de Sweet Alert para mostrar una alerta como la de la imagen del inicio, si desea ver ejemplos de los diferentes tipos de alertas de Sweet Alert, puede visitar el siguiente enlace: https://sweetalert2.github.io/#examples

Importar la librería Sweet Alert

Primero debemos importar la librería de Sweet Alert en Oracle APEX, en mi caso me gusta hacerlo en las propiedades del proyecto, ya que así lo puedo utilizar en todo el proyecto cuando lo necesite:

https://cdn.jsdelivr.net/npm/sweetalert2@11

Implementar el código

Luego en la página que queramos mostrar la alerta, debemos crear un dynamic action antes de la ejecución del proceso PL/SQL, esta acción dinámica debe ejecutar un script de tipo javascript:

El código que utilizaremos será el siguiente:

Nota: Cuando el mensaje se muestre, durará 5 segundos, es necesario colocar un valor alto, ya que cuando la ejecución de nuestro PL/SQL termine, el mensaje desaparecerá, por lo que es mejor colocar un tiempo alto para evitar mostrar pantallas en blanco al usuario. Este tiempo se puede cambiar en el parámetro timer.

let timerInterval
Swal.fire({
  title: 'Espere porfavor...',
  html: 'No cierre la ventana del navegador',
  timer: 5000,
  timerProgressBar: true,
  didOpen: () => {
    Swal.showLoading()
    timerInterval = setInterval(() => {
      const content = Swal.getHtmlContainer()
      if (content) {
        const b = content.querySelector('b')
        if (b) {
          b.textContent = Swal.getTimerLeft()
        }
      }
    }, 100)
  },
  willClose: () => {
    clearInterval(timerInterval)
  }
}).then((result) => {
  /* Read more about handling dismissals below */
  if (result.dismiss === Swal.DismissReason.timer) {
    //console.log('I was closed by the timer')
  }
})

Luego crearemos otra acción dinámica debajo, esta será de tipo ejecución de PL/SQL:

En mi caso el código a utilizar, será para realizar una consulta a un API, el proceso de consulta es corto y dura aproximadamente 5 segundos en terminar y brindarme el response.

Acá es donde deberá colocar la consulta PL/SQL que toma un tiempo en retornar los valores y el tiempo de duración de la pantalla de carga, lo puede cambiar en el parámetro timer de la acción dinámica anterior:

Declare
res VARCHAR(100);
montoTotal NUMBER(15,2);

begin
select sum(DISTINCT L.PRECIO_CANTIDAD) AS PRECIO_POR_CANTIDAD INTO montoTotal
  from LISTA_PRODUCTO_EN_CARRITO L, PRODUCTO P, IMAGEN_PRODUCTO I, USUARIO U 
  where L.ID_PRODUCTO = P.ID_PRODUCTO 
  AND I.ID_PRODUCTO = P.ID_PRODUCTO 
  AND I.PRESENTACION = 1
  AND L.ID_ESTADO_PRODUCTO_CARRITO = 1
  AND L.ID_USUARIO = (select ID_USUARIO from usuario where lower(USUARIO) = lower(:APP_USER));

SELECT utl_http.request('http://192.168.1.50:8081/PagosElectronicos-1.0/resources/pagos?amount='|| montoTotal ||'&description=Compra+productos&entity_description=Compra+productos&currency=crc&credit_card_number='|| :P13_NUMERO_TARJETA ||'&credit_card_security_code_number='|| :P13_CODIGO_SEGURIDAD ||'&exp_month='|| :P13_MES_EXPIRACION ||'&exp_year='|| :P13_ANO_EXPIRACION ) as Consulta_API into res FROM dual;


:P13_RESPUESTA_API_PAGOS := res;
apex_util.set_session_state('P13_RESPUESTA_API_PAGOS', res);

end;

Por último, crearemos otra acción dinámica de tipo javascript, esta nos mostrará otro mensaje luego de haber terminado la consulta:

Esta ves el código a utilizar será el siguiente:

if(apex.item("P13_RESPUESTA_API_PAGOS").getValue() == 'Pago realizado satisfactoriamente.'){
Swal.fire(
  apex.item("P13_RESPUESTA_API_PAGOS").getValue(),
  '',
  'success'
)
}else{
Swal.fire({
  icon: 'error',
  title: 'Error',
  text: apex.item("P13_RESPUESTA_API_PAGOS").getValue(),
  //footer: '<a href>Why do I have this issue?</a>'
})
}

Dependiendo la respuesta del PL/SQL, yo almaceno la respuesta en un item oculto y luego en el código de javascript lo consulto, ya sea para mostrar un mensaje de error o mensaje satisfactorio.

Prueba de ejecución

Por último, probaremos la ejecución del código, guardamos los cambios y hacemos la prueba:

Cuando presionamos el botón, se mostrará la pantalla de carga, durará 5 segundos, sin embargo, si la consulta PL/SQL dura menos, el mensaje desaparecerá y se cambiará por el siguiente, si la consulta dura más, entonces el tiempo del timer debería ser mayor:

Si el mensaje de respuesta del API es satisfactorio, me mostrará la siguiente alerta:

En el caso contrario, me mostrará una alerta de error:

Sweet Alert posee varios tipos de alertas, donde podemos incluir desde imágenes, hasta fondos animados, utilizar esta librería en conjunto con Oracle APEX, nos brindará una experiencia de usuario, mucho más amena.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *