Personalizar Interactive Grid de Oracle APEX: Botones y Acciones Personalizadas.
El Interactive Grid (IG) de Oracle APEX es una herramienta poderosa que permite gestionar y visualizar datos de manera flexible y altamente interactiva. Sin embargo, en ciertos proyectos tal vez sea necesario añadir funcionalidades adicionales, como botones y acciones personalizadas, que no vienen preconfigurados en el IG. En esta publicación, aprenderás a añadir botones con acciones personalizadas usando JavaScript.
Antes de empezar pueden encontrar una hoja de trucos y acciones de la IG AQUI en un articulo de Osvaldo González
Por qué Personalizar el Interactive Grid
La personalización del Interactive Grid nos permite adaptar la herramienta a las necesidades específicas de la aplicación y mejorar la experiencia del usuario. Al agregar botones y acciones personalizadas, puedes automatizar tareas, mostrar alertas o enviar datos al servidor, extendiendo así la funcionalidad predeterminada de Oracle APEX.
Al crear nuestra IG tenemos que habilitar la opcion de EDITAR que se encuentra en la seccion de atributos.

En la misma pestaña los desplazamos mas abajo hasta la opcion de “Función de inicialización JavaScript” y pegamos ahi el siguiente codigo.
function(config) {
let $ = apex.jQuery,
toolbarData = $.apex.interactiveGrid.copyDefaultToolbar(),
//buscamos el grupo search
toolbarGroup = toolbarData.toolbarFind("search");
// Agregando el primer botón en el grupo "search"
toolbarGroup.controls.push({
type: "BUTTON",//definimos el tipo boton
label: "boton1",//definimos el label
action: "alerta",//llamamos a esta funcion que vamos a crear
icon: "icon-ig-add-row",//agregamos un icono personalizado, si no se
//quiere usar icon solo se deja vacio asi ""
iconBeforeLabel: false, //con false se muestra el icono despues del
//label con true, se muestra antes del label
hot: true// true resalta el boton, con false lo deja sin resaltado.
});
//creamos la funcion alerta que usamos arriba
config.initActions = function(actions) {
actions.add({
name: "alerta",
action: function() {
alert('Esta es una acción personalizada');
}
});
}
config.toolbarData = toolbarData;
return config;
}
Al ejecutar la pagina tendriamos lo siguiente

Al darle clic, se ejecuta la funcion que creamos.

Podemos crear varios botones mas usando el mismo codigo y agrupandolos en la seccion de los botones que usualmente tenemos y usamos.
Asi usando este nuevo codigo.
function(config) {
let $ = apex.jQuery,
toolbarData = $.apex.interactiveGrid.copyDefaultToolbar(),
//buscamos el grupo search
toolbarGroup = toolbarData.toolbarFind("search");
// Agregando el primer botón en el grupo "search"
toolbarGroup.controls.push({
type: "BUTTON", //definimos el tipo boton
label: "boton1", //definimos el label
action: "alerta", //llamamos a esta funcion que vamos a crear
icon: "icon-ig-add-row", //agregamos un icono personalizado, si no se
//quiere usar icon solo se deja vacio asi ""
iconBeforeLabel: false, //con false se muestra el icono despues del
//label con true, se muestra antes del label
hot: true // true resalta el boton, con false lo deja sin resaltado.
});
toolbarGroup = toolbarData.toolbarFind("reports");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton2",
action: "apexCallback",
icon: "fa fa-pencil-square-o",
iconBeforeLabel: false,
hot: false
});
toolbarGroup = toolbarData.toolbarFind("views");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton3",
action: "alerta",
icon: "fa fa-ai-generative",
iconBeforeLabel: false,
hot: false
});
toolbarGroup = toolbarData.toolbarFind("actions1");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton4",
action: "alerta",
icon: "fa fa-american-sign-language-interpreting",
iconBeforeLabel: true,
hot: true
});
toolbarGroup = toolbarData.toolbarFind("actions2");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton5",
action: "alerta",
icon: "",
iconBeforeLabel: false,
hot: true
});
toolbarGroup = toolbarData.toolbarFind("actions3");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton6",
action: "alerta",
icon: "",
iconBeforeLabel: false,
hot: true
});
toolbarGroup = toolbarData.toolbarFind("actions4");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton7",
action: "alerta",
icon: "",
iconBeforeLabel: false,
hot: true
});
config.initActions = function(actions) {
actions.add({
name: "alerta",
action: function() {
alert('Esta es una acción personalizada');
}
});
}
config.toolbarData = toolbarData;
return config;
}
Estariamos agregando 7 botones nuevos.

A cada uno de estos botones de pueden agregar acciones personalizadas, se podria agregar como funcion un poceso ajax utilizando apex.server.process asi.
Creamos un proceso en la seccion de “Devolucion de llamada ajax”

En el codigo plsql agregue lo siguiente, cuyo l_mensaje puedo capturar y mostrar por consola.
declare
l_mensaje varchar2(2000);
l_succes boolean;
begin
l_mensaje:='El hombre no puede obtener nada sin primero dar algo a cambio. Para crear, algo de igual valor debe darse a cambio';
l_succes:=true;
apex_json.open_object;
apex_json.write('success', l_succes);
apex_json.write('message', l_mensaje);
apex_json.close_object;
exception
when others then
l_mensaje:='keep calm and write more code';
l_succes:=false;
apex_json.open_object;
apex_json.write('success', l_succes);
apex_json.write('message', l_mensaje);
apex_json.close_object;
end;
Ese proceso lo podemos llamar con javascript en nuestra nueva accion junto con la ya existente “alerta”.
config.initActions = function(actions) {
// Añadir la acción apexajax
actions.add({
name: "apexajax",
action: function() {
apex.server.process("llamarPackage", {
x01: $v("P11_IR"), // Envío de parámetro con x01
pageItems: "#P11_IR" // Envío de parámetro con pageItems
}, {
success: function(data) {
// Lógica para procesar el JSON entrante
apex.debug.setLevel(4); // Definimos el nivel de registro en info=4
apex.debug.info(data.message);
},
error: function(jqXHR, textStatus, errorThrown) {
// Lógica para procesar errores
var errorMessage = "Operación fallida: " + textStatus + " - " + errorThrown;
apex.debug.error(errorMessage);
}
});
}
});
// Añadir la acción alerta
actions.add({
name: "alerta",
action: function() {
alert('Esta es una acción personalizada');
}
});
}
El codigo completo ya con los botones quedaria asi.
function(config) {
let $ = apex.jQuery,
toolbarData = $.apex.interactiveGrid.copyDefaultToolbar(),
toolbarGroup = toolbarData.toolbarFind("search");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton1",
action: "alerta",
icon: "icon-ig-add-row",
iconBeforeLabel: false,
hot: true
});
toolbarGroup = toolbarData.toolbarFind("reports");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton2",
action: "apexajax",
icon: "fa fa-pencil-square-o",
iconBeforeLabel: false,
hot: true
});
toolbarGroup = toolbarData.toolbarFind("views");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton3",
action: "alerta",
icon: "fa fa-ai-generative",
iconBeforeLabel: false,
hot: true
});
toolbarGroup = toolbarData.toolbarFind("actions1");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton4",
action: "alerta",
icon: "fa fa-american-sign-language-interpreting",
iconBeforeLabel: false,
hot: true
});
toolbarGroup = toolbarData.toolbarFind("actions2");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton5",
action: "alerta",
icon: "",
iconBeforeLabel: false,
hot: true
});
toolbarGroup = toolbarData.toolbarFind("actions3");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton6",
action: "alerta",
icon: "",
iconBeforeLabel: false,
hot: true
});
toolbarGroup = toolbarData.toolbarFind("actions4");
toolbarGroup.controls.push({
type: "BUTTON",
label: "boton7",
action: "alerta",
icon: "",
iconBeforeLabel: false,
hot: true
});
config.initActions = function(actions) {
// Añadir la acción apexajax
actions.add({
name: "apexajax",
action: function() {
apex.server.process("llamarPackage", {
x01: $v("P11_IR"), // Envío de parámetro con x01
pageItems: "#P11_IR" // Envío de parámetro con pageItems
}, {
success: function(data) {
// Lógica para procesar el JSON entrante
apex.debug.setLevel(4); // Definimos el nivel de registro en info=4
apex.debug.info(data.message);
},
error: function(jqXHR, textStatus, errorThrown) {
// Lógica para procesar errores
var errorMessage = "Operación fallida: " + textStatus + " - " + errorThrown;
apex.debug.error(errorMessage);
}
});
}
});
// Añadir la acción alerta
actions.add({
name: "alerta",
action: function() {
alert('Esta es una acción personalizada');
}
});
}
config.toolbarData = toolbarData;
return config;
}
Elegimos el “boton2” para llamar a la nueva accion y al ejecutar tendriamos algo asi.

Como podemos observar funciona correctamente ambas acciones juntas.
Ventajas de Personalizar el Interactive Grid
Agregar acciones personalizadas y botones en la barra de herramientas del Interactive Grid ofrece varios beneficios:
Mejora la experiencia del usuario: los usuarios pueden interactuar con el IG de una manera más intuitiva y personalizada.
Automatiza procesos: permite ejecutar llamadas al servidor o mostrar alertas en el momento preciso, ahorrando tiempo al usuario.
Extiende la funcionalidad nativa: puedes integrar procesos avanzados sin necesidad de herramientas externas.
Conclusión
El Interactive Grid de Oracle APEX es una herramienta muy flexible y altamente personalizable. Con código como el que hemos explorado aquí, puedes crear una experiencia de usuario mucho más enriquecida y adaptar tu aplicación a las necesidades específicas de tu organización o proyecto.
Personalizar la barra de herramientas y las acciones en el Interactive Grid es solo el comienzo. ¡Experimenta con diferentes configuraciones y acciones para descubrir todo lo que puedes lograr con Oracle APEX!
