⚡ Funciones JavaScript y Espacio de Nombres Ragnos
Este documento describe las funciones utilitarias getValue y getObject, así como la arquitectura del espacio de nombres unificado window.Ragnos utilizado en el proyecto para realizar peticiones asíncronas, manipulación de tablas y componentes de UI.
Espacio de Nombres Global Ragnos.*
Todas las funciones utilitarias y componentes de JavaScript del cliente están organizados limpiamente dentro del espacio de nombres window.Ragnos:
Ragnos.Http: Peticiones AJAX y redirecciones (getValue,getObject,postFormData,fixUrl, etc.).Ragnos.UI: Notificaciones Toast, Modales y feedback visual (showToast,showModal,cierraModal,mostrarCargando, etc.).Ragnos.Table: DataTables y exportación/totales en tablas (destroyDataTable,ponTablaPaginada,exportToExcel, etc.).Ragnos.DOM: Manipulación DOM y helpers (onReady,getElement,debounce,moneyFormat, etc.).Ragnos.Search,Ragnos.Editor,Ragnos.Utils,Ragnos.Stack: Componentes deragnos.js.
Para mantener 100% de retrocompatibilidad, todas las funciones y clases continúan estando disponibles como alias globales directos (getValue, showToast, RagnosSearch, etc.).
getValue(url, params, callback)
Realiza una petición HTTP POST a una URL especificada y devuelve la respuesta como texto plano.
Parámetros
url(string): La URL a la que se realizará la petición. Se procesa internamente confixUrl, por lo que puede ser una ruta relativa.params(object, opcional): Un objeto con los parámetros que se enviarán en el cuerpo de la petición (codificados comoapplication/x-www-form-urlencoded).- Además de los datos a enviar, este objeto acepta configuraciones especiales:
timeout(number): Tiempo máximo de espera en milisegundos (por defecto: 12000).retryAttempts(number): Número de intentos en caso de fallo (por defecto: 1).retryDelay(number): Retardo entre intentos en milisegundos (por defecto: 1000).
callback(function, opcional): Una función que se ejecutará al completar la petición. Recibe dos argumentos:(response, error).
Retorno
- Si se proporciona un
callback, la función no retorna nada y el resultado se maneja en el callback. - Si no se proporciona un
callback, devuelve unaPromiseque resuelve con el texto de la respuesta o rechaza con un error.
Ejemplos de uso
Moderniza tu código
Aunque soportan callbacks, recomendamos fuertemente usar la sintaxis async/await para un código más limpio y legible, evitando el "callback hell".
Uso básico con Promesas (Async/Await):
try {
const respuestaTexto = await getValue("controller/metodo", { id: 123 });
console.log("Respuesta del servidor:", respuestaTexto);
} catch (error) {
console.error("Hubo un error:", error);
}
Uso con Callback:
getValue("controller/metodo", { usuario: "juan" }, function (response, error) {
if (error) {
console.error("Error:", error);
} else {
console.log("Respuesta:", response);
}
});
Configuración de timeout y reintentos:
const params = {
dato: "valor",
timeout: 5000, // Esperar máximo 5 segundos
retryAttempts: 3, // Reintentar hasta 3 veces si falla
};
try {
const res = await getValue("api/data", params);
} catch (e) {
console.error("Falló tras 3 intentos");
}
getObject(purl, pparameters, callbackfunction)
Es una función envolvente (wrapper) de getValue. Realiza la petición y automáticamente intenta parsear la respuesta como un objeto JSON.
Parámetros
purl(string): La URL a la que se realizará la petición.pparameters(object): Objeto con los parámetros a enviar.callbackfunction(function, opcional): Función de callback que recibe(objeto, error).objeto: El resultado parseado como JSON si todo salió bien (onullsi hubo error).error: Objeto de error si la petición falló o el JSON no es válido (onullsi todo salió bien).
Retorno
- Si se usa
callbackfunction, no retorna nada explícito. - Si no se usa
callbackfunction, devuelve unaPromiseque resuelve con el objeto JavaScript parseado o rechaza con el error.
Ejemplos de uso
Uso básico para obtener datos JSON:
// Supongamos que el servidor devuelve: {"nombre": "Ragnos", "version": 1.0}
try {
const data = await getObject("api/config", { modulo: "admin" });
console.log("Nombre del sistema:", data.nombre);
} catch (error) {
console.error("Error obteniendo configuración:", error);
}
Uso con Callback:
getObject("clientes/buscar", { q: "Empresa X" }, function (clientes, error) {
if (error) {
alert("Error en la búsqueda");
return;
}
// 'clientes' ya es un array u objeto JS
clientes.forEach((c) => console.log(c.nombre));
});
RagnosSearch y Clases relacionadas
La clase RagnosSearch y sus métodos auxiliares proporcionan una interfaz estandarizada para realizar búsquedas en inputs, integrando interfaz gráfica (botones) y manejo de resultados.
RagnosSearch.setupSimpleSearch(elemento, ruta, params, callback)
Método estático para configurar una búsqueda sencilla en un input existente. Transforma el input agregando o reutilizando botones de búsqueda y limpieza en un grupo de entrada (.input-group), protegiendo la idempotencia mediante la marca Ragnosffied.
Parámetros
elemento(string | DOM Element): El selector CSS o elemento DOM input donde se habilitará la búsqueda.ruta(string): La URL del servidor (Controlador/Método) que procesará la búsqueda.params(object): Configuración adicional.canSetToNull(boolean): Define si se muestra el botón "X" para limpiar el campo (Default:true).callback(function, opcional): Función a ejecutar tras una búsqueda o limpieza exitosa. Recibe el elemento DOM del input como argumentoe.
Retorno
- Devuelve el elemento
HTMLInputElementconfigurado (onullsi el elemento no es válido). Retorna tempranamente si el control ya fue marcado conRagnosffied.
Características Destacadas
- Idempotencia (
Ragnosffied): Evita la duplicación de listeners y botones si la función se invoca múltiples veces sobre el mismo control. - Búsqueda por Botón y Tecla
Enter: Al hacer clic en la lupa o presionarEnter, ejecuta la búsqueda enviando el valor actual del input (input.value) y previene el envío accidental del formulario. - Sincronización de Estado y Campos Ocultos: Al vaciar el input o pulsar el botón de limpieza "X", resetea
input.ragnosSearchData = nully limpia cualquier campohiddenasociado. - Soporte para Hooks por Convención: Al completar una búsqueda o limpiar el campo, busca y ejecuta automáticamente la función global
_{id}OnSearch(control)o_{name}OnSearch(control)si está definida encustom.js.
Ejemplo de uso
RagnosSearch.setupSimpleSearch(
document.querySelector("#miInput"),
"admin/usuarios/buscar",
{},
function (e) {
// Los datos del resultado se adjuntan al elemento DOM
const resultado = e.ragnosSearchData;
if (resultado) {
console.log("ID seleccionado:", resultado.id);
console.log("Nombre:", resultado.nombre);
// Asignar valor al input visible
e.value = resultado.nombre;
}
},
);
new RagnosSearch(elemento, params)
Clase nativa para búsquedas más complejas, típicamente vinculadas a un controlador estándar del sistema (RagnosController) que implementa searchByAjax y soporta filtros estructurados.
Parámetros (params)
Objeto de configuración con:
controller(string): Nombre del controlador que gestiona la búsqueda (ej.'usuarios','productos'). El sistema buscará encontroller/searchByAjax.filter(string): Cadena en Base64 que contiene un array JSON de filtros.- Estructura:
Base64( JSON_String([ {field, op, value}, ... ]) ). callback(function): Función a ejecutar al seleccionar un resultado.canSetToNull(boolean): (Opcional) Permite limpiar el campo.
Ejemplo de uso
new RagnosSearch(document.querySelector("#inputBusquedaAvanzada"), {
controller: "usuarios", // Busca en: usuarios/searchByAjax
// Filtro: Usuarios activos (usu_activo = 'S') y del grupo 2
filter: btoa(
JSON.stringify([
{ field: "usu_activo", op: "=", value: "S" },
{ field: "usu_grupo", op: "=", value: 2 },
]),
),
callback: function (e) {
const datos = e.ragnosSearchData;
console.log("Datos recibidos:", datos);
if (datos && datos.id) {
// Lógica personalizada
}
},
});
Hooks de Sistema y Funciones en custom.js
El archivo custom.js es el lugar designado para lógica específica de la aplicación, incluyendo "hooks" (ganchos) que el sistema invoca automáticamente basándose en convenciones de nombres. Esto permite extender la funcionalidad de búsquedas y tablas sin modificar el núcleo.
Convención de Nombres para Hooks
El sistema detecta automáticamente funciones globales con patrones específicos de nombre para ejecutar acciones tras ciertos eventos.
1. Hooks de Búsqueda (_NombreCampoOnSearch)
Se ejecutan automáticamente después de que un control RagnosSearch completa una selección.
- Patrón:
_{id_del_input}OnSearch - Parámetro: Recibe el elemento DOM del control (input).
- Uso: Ideal para rellenar otros campos del formulario basándose en el resultado de la búsqueda.
Ejemplo del sistema (_productCodeOnSearch):
Cuando se selecciona un producto en el input productCode, esta función busca el input priceEach en el detalle de la orden y le asigna el precio sugerido (MSRP).
// Se activa al seleccionar algo en <input id="productCode" ...>
function _productCodeOnSearch(control) {
// 'control' es el input del código de producto
// Accedemos a los datos devueltos por la búsqueda
const datos = control.ragnosSearchData;
// Actualizamos otro campo (Precio Unitario) con el valor MSRP del producto
document.querySelector('#detalleorden input[name="priceEach"]').value =
datos.MSRP;
}
2. Hooks de Cambio en Tabla (_NombreTablaOnChange)
Se ejecutan cuando ocurre un cambio en una tabla gestionada (por ejemplo, al agregar o editar filas en una tabla detalle).
- Patrón:
_{id_de_la_tabla}OnChange - Parámetro: Recibe el objeto tabla o el contexto del cambio.
- Uso: Recálculos de totales, validaciones cruzadas.
Ejemplo del sistema (_OrdenesdetallesOnChange):
Cada vez que cambia algo en la tabla de detalles de órdenes (Ordenesdetalles), se recalcula el total de la orden completa llamando al servidor.
// Se activa al modificar la tabla <table id="Ordenesdetalles" ...>
function _OrdenesdetallesOnChange(tabla) {
// Obtenemos el ID de la orden actual
const orden = document.querySelector("input[name='orderNumber']").value;
// Llamamos al servidor para recalcular el total
getObject("tienda/ordenes/calculatotal", { orden: orden }, function (data) {
// Actualizamos el campo visual de Total
document.querySelector('input[name="total"]').value = data.total;
});
}
Funciones Utilitarias Personalizadas
También se pueden definir funciones normales para ser usadas como callbacks explícitos en configuraciones de búsqueda.
Ejemplo (pruebaBusquedaOffice):
Una función simple diseñada para ser pasada como parámetro callback en RagnosSearch.
function pruebaBusquedaOffice(e) {
const datos = e.ragnosSearchData;
console.log("Los datos de la busqueda por oficina", datos);
}
// Uso:
// new RagnosSearch('#oficina', { ..., callback: pruebaBusquedaOffice });
RagnosUtils.showControllerTableIn(selector, controller, master)
Carga de forma asíncrona la tabla generada por un controlador en un elemento específico del DOM. Esta función es fundamental cuando se manejan relaciones de "Detalle" o cuando se quiere incrustar una vista de tabla de forma dinámica.
Parámetros
selector(string | DOM Element): Selector CSS (ej.'#mi_tabla_detalle') o elemento donde se inyectará el contenido HTML.controller(string): Nombre del controlador (o ruta URL) que responderá la petición. Internamente llama al métodotableByAjaxdel controlador.master(string, opcional): El ID del registro maestro. Si se proporciona, se asocia al objeto global de seguridadRagnos_csrfpara filtrar los resultados por este ID padre.
Ejemplo de uso
// Cargar la tabla de detalles de una orden específica
const idOrden = "10123";
RagnosUtils.showControllerTableIn(
"#contenedor-detalles",
"ventas/detalles",
idOrden,
);
RagnosUtils.showControllerReportIn(selector, controller)
Similar a showControllerTableIn, pero diseñada específicamente para cargar vistas de reportes generadas por el controlador.
Parámetros
selector(string | DOM Element): Selector CSS o elemento donde se inyectará el reporte.controller(string): Nombre del controlador. Internamente llama al métodoreportByAjaxdel controlador.